Repository: NangoHQ/integration-templates
Pull request #322: feat(gusto): update employee actions
Author: login: kaposke
Created: 2025-05-09T16:10:07Z | Merged: 2025-05-12T08:27:57Z

## Describe your changes

## Issue ticket number and link

## Checklist before requesting a review (skip if just adding/editing APIs & templates)

-   [ ] I added tests, otherwise the reason is:
-   [ ] External API requests have `retries`
-   [ ] Pagination is used where appropriate
-   [ ] The built in `nango.paginate` call is used instead of a `while (true)` loop
-   [ ] Third party requests are NOT parallelized (this can cause issues with rate limits)
-   [ ] If a sync requires metadata the `nango.yaml` has `auto_start: false`
-   [ ] If the sync is a `full` sync then `track_deletes: true` is set
-   [ ] I followed the best practices and guidelines from the [Writing Integration Scripts](/NangoHQ/integration-templates/blob/main/guides/WRITING_SCRIPTS.md) doc



Diff:
diff --git a/flows.yaml b/flows.yaml
index 9877e75a0..8c86a1aa0 100644
--- a/flows.yaml
+++ b/flows.yaml
@@ -6764,40 +6764,37 @@ integrations:
                 openings: string[]
     gusto:
         actions:
-            create-user:
-                description: Creates a user in Gusto.
-                output: User
+            create-employee:
+                description: Creates an employee in Gusto.
+                output: GustoCreateEmployeeResponse
                 endpoint:
                     method: POST
-                    path: /users
-                    group: Users
-                input: GustoCreateUser
+                    path: /employees
+                    group: Employees
+                input: GustoCreateEmployee
                 scopes:
                     - employees:manage
-            delete-user:
-                description: Deletes a user in Gusto.
+            update-employee:
+                description: Updates an employee in Gusto.
+                output: GustoUpdateEmployeeResponse
+                endpoint:
+                    method: PUT
+                    path: /employees
+                    group: Employees
+                input: GustoUpdateEmployee
+                scopes:
+                    - employees:manage
+            terminate-employee:
+                description: Terminates an employee in Gusto.
                 endpoint:
                     method: DELETE
-                    path: /users
-                    group: Users
+                    path: /employees
+                    group: Employees
                 output: SuccessResponse
-                input: GustoDeleteUser
+                input: GustoTerminateEmployee
                 scopes:
                     - employments:write
         syncs:
-            users:
-                runs: every day
-                description: |
-                    Fetches a list of users from Gusto.
-                output: User
-                track_deletes: true
-                sync_type: full
-                endpoint:
-                    method: GET
-                    path: /users
-                    group: Users
-                scopes:
-                    - employees:read
             employees:
                 runs: every 5m
                 description: Fetches all employees from Gusto
@@ -6825,16 +6822,7 @@ integrations:
                 success: boolean
             IdEntity:
                 id: string
-            User:
-                id: string
-                email: string
-                firstName: string
-                lastName: string
-            CreateUser:
-                firstName: string
-                lastName: string
-                email: string
-            GustoCreateUser:
+            GustoCreateEmployee:
                 firstName: string
                 lastName: string
                 email: string
@@ -6843,7 +6831,28 @@ integrations:
                 dateOfBirth: string
                 ssn?: string
                 selfOnboarding?: boolean
-            GustoDeleteUser:
+            GustoCreateEmployeeResponse:
+                id: string
+                email: string
+                firstName: string
+                lastName: string
+            GustoUpdateEmployee:
+                id: string
+                version: string
+                firstName?: string
+                lastName?: string
+                email?: string
+                middleInitial?: string
+                preferredFirstName?: string
+                dateOfBirth?: string
+                ssn?: string
+                twoPercentShareholder?: boolean
+            GustoUpdateEmployeeResponse:
+                id: string
+                email: string
+                firstName: string
+                lastName: string
+            GustoTerminateEmployee:
                 id: string
                 effectiveDate?: string
                 runTerminationPayroll?: boolean
@@ -6923,40 +6932,37 @@ integrations:
                 address: string
     gusto-demo:
         actions:
-            create-user:
-                description: Creates a user in Gusto.
-                output: User
+            create-employee:
+                description: Creates an employee in Gusto.
+                output: GustoCreateEmployeeResponse
                 endpoint:
                     method: POST
-                    path: /users
-                    group: Users
-                input: GustoCreateUser
+                    path: /employees
+                    group: Employees
+                input: GustoCreateEmployee
                 scopes:
                     - employees:manage
-            delete-user:
-                description: Deletes a user in Gusto.
+            update-employee:
+                description: Updates an employee in Gusto.
+                output: GustoUpdateEmployeeResponse
+                endpoint:
+                    method: PUT
+                    path: /employees
+                    group: Employees
+                input: GustoUpdateEmployee
+                scopes:
+                    - employees:manage
+            terminate-employee:
+                description: Terminates an employee in Gusto.
                 endpoint:
                     method: DELETE
-                    path: /users
-                    group: Users
+                    path: /employees
+                    group: Employees
                 output: SuccessResponse
-                input: GustoDeleteUser
+                input: GustoTerminateEmployee
                 scopes:
                     - employments:write
         syncs:
-            users:
-                runs: every day
-                description: |
-                    Fetches a list of users from Gusto.
-                output: User
-                track_deletes: true
-                sync_type: full
-                endpoint:
-                    method: GET
-                    path: /users
-                    group: Users
-                scopes:
-                    - employees:read
             employees:
                 runs: every 5m
                 description: Fetches all employees from Gusto
@@ -6984,16 +6990,7 @@ integrations:
                 success: boolean
             IdEntity:
                 id: string
-            User:
-                id: string
-                email: string
-                firstName: string
-                lastName: string
-            CreateUser:
-                firstName: string
-                lastName: string
-                email: string
-            GustoCreateUser:
+            GustoCreateEmployee:
                 firstName: string
                 lastName: string
                 email: string
@@ -7002,7 +6999,28 @@ integrations:
                 dateOfBirth: string
                 ssn?: string
                 selfOnboarding?: boolean
-            GustoDeleteUser:
+            GustoCreateEmployeeResponse:
+                id: string
+                email: string
+                firstName: string
+                lastName: string
+            GustoUpdateEmployee:
+                id: string
+                version: string
+                firstName?: string
+                lastName?: string
+                email?: string
+                middleInitial?: string
+                preferredFirstName?: string
+                dateOfBirth?: string
+                ssn?: string
+                twoPercentShareholder?: boolean
+            GustoUpdateEmployeeResponse:
+                id: string
+                email: string
+                firstName: string
+                lastName: string
+            GustoTerminateEmployee:
                 id: string
                 effectiveDate?: string
                 runTerminationPayroll?: boolean
diff --git a/integrations/gusto/.nango/schema.json b/integrations/gusto/.nango/schema.json
index 5ce45fde7..85d990f37 100644
--- a/integrations/gusto/.nango/schema.json
+++ b/integrations/gusto/.nango/schema.json
@@ -21,44 +21,65 @@
             "required": ["id"],
             "additionalProperties": false
         },
-        "User": {
+        "GustoCreateEmployee": {
             "type": "object",
             "properties": {
-                "id": {
+                "firstName": {
+                    "type": "string"
+                },
+                "lastName": {
                     "type": "string"
                 },
                 "email": {
                     "type": "string"
                 },
-                "firstName": {
+                "middleInitial": {
                     "type": "string"
                 },
-                "lastName": {
+                "preferredFirstName": {
+                    "type": "string"
+                },
+                "dateOfBirth": {
+                    "type": "string"
+                },
+                "ssn": {
                     "type": "string"
+                },
+                "selfOnboarding": {
+                    "type": "boolean"
                 }
             },
-            "required": ["id", "email", "firstName", "lastName"],
+            "required": ["firstName", "lastName", "email", "dateOfBirth"],
             "additionalProperties": false
         },
-        "CreateUser": {
+        "GustoCreateEmployeeResponse": {
             "type": "object",
             "properties": {
-                "firstName": {
+                "id": {
                     "type": "string"
                 },
-                "lastName": {
+                "email": {
                     "type": "string"
                 },
-                "email": {
+                "firstName": {
+                    "type": "string"
+                },
+                "lastName": {
                     "type": "string"
                 }
             },
-            "required": ["firstName", "lastName", "email"],
+            "required": ["id", "email", "firstName", "lastName"],
             "additionalProperties": false
         },
-        "GustoCreateUser": {
+        "GustoUpdateEmployee": {
             "type": "object",
             "properties": {
+                "id": {
+                    "type": "string"
+                },
+                "version": {
+                    "type": "string"
+                },
                 "firstName": {
                     "type": "string"
                 },
@@ -80,14 +101,33 @@
                 "ssn": {
                     "type": "string"
                 },
-                "selfOnboarding": {
+                "twoPercentShareholder": {
                     "type": "boolean"
                 }
             },
-            "required": ["firstName", "lastName", "email", "dateOfBirth"],
+            "required": ["id", "version"],
+            "additionalProperties": false
+        },
+        "GustoUpdateEmployeeResponse": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "string"
+                },
+                "email": {
+                    "type": "string"
+                },
+                "firstName": {
+                    "type": "string"
+                },
+                "lastName": {
+                    "type": "string"
+                }
+            },
+            "required": ["id", "email", "firstName", "lastName"],
             "additionalProperties": false
         },
-        "GustoDeleteUser": {
+        "GustoTerminateEmployee": {
             "type": "object",
             "properties": {
                 "id": {
@@ -414,5 +454,5 @@
             "additionalProperties": false
         }
     },
-    "$comment": "This file was generated by Nango (v0.58.3)"
+    "$comment": "This file was generated by Nango (v0.57.3)"
 }
diff --git a/integrations/gusto/.nango/schema.ts b/integrations/gusto/.nango/schema.ts
index e935bc223..5bc298285 100644
--- a/integrations/gusto/.nango/schema.ts
+++ b/integrations/gusto/.nango/schema.ts
@@ -1,5 +1,5 @@
 // ---------------------------
-// This file was generated by Nango (v0.58.3)
+// This file was generated by Nango (v0.57.3)
 // You can version this file
 // ---------------------------
 
@@ -11,31 +11,45 @@ export interface IdEntity {
     id: string;
 }
 
-export interface User {
-    id: string;
-    email: string;
+export interface GustoCreateEmployee {
     firstName: string;
     lastName: string;
+    email: string;
+    middleInitial?: string;
+    preferredFirstName?: string;
+    dateOfBirth: string;
+    ssn?: string;
+    selfOnboarding?: boolean;
 }
 
-export interface CreateUser {
+export interface GustoCreateEmployeeResponse {
+    id: string;
+    email: string;
     firstName: string;
     lastName: string;
-    email: string;
 }
 
-export interface GustoCreateUser {
-    firstName: string;
-    lastName: string;
-    email: string;
+export interface GustoUpdateEmployee {
+    id: string;
+    version: string;
+    firstName?: string;
+    lastName?: string;
+    email?: string;
     middleInitial?: string;
     preferredFirstName?: string;
-    dateOfBirth: string;
+    dateOfBirth?: string;
     ssn?: string;
-    selfOnboarding?: boolean;
+    twoPercentShareholder?: boolean;
+}
+
+export interface GustoUpdateEmployeeResponse {
+    id: string;
+    email: string;
+    firstName: string;
+    lastName: string;
 }
 
-export interface GustoDeleteUser {
+export interface GustoTerminateEmployee {
     id: string;
     effectiveDate?: string;
     runTerminationPayroll?: boolean;
diff --git a/integrations/gusto/actions/create-user.md b/integrations/gusto/actions/create-employee.md
similarity index 73%
rename from integrations/gusto/actions/create-user.md
rename to integrations/gusto/actions/create-employee.md
index 2d34c677a..3d433e120 100644
--- a/integrations/gusto/actions/create-user.md
+++ b/integrations/gusto/actions/create-employee.md
@@ -1,21 +1,21 @@
 <!-- BEGIN GENERATED CONTENT -->
-# Create User
+# Create Employee
 
 ## General Information
 
-- **Description:** Creates a user in Gusto.
+- **Description:** Creates an employee in Gusto.
 - **Version:** 0.0.1
-- **Group:** Users
+- **Group:** Employees
 - **Scopes:** `employees:manage`
 - **Endpoint Type:** Action
-- **Code:** [github.com](https://github.com/NangoHQ/integration-templates/tree/main/integrations/gusto/actions/create-user.ts)
+- **Code:** [github.com](https://github.com/NangoHQ/integration-templates/tree/main/integrations/gusto/actions/create-employee.ts)
 
 
 ## Endpoint Reference
 
 ### Request Endpoint
 
-`POST /users`
+`POST /employees`
 
 ### Request Query Parameters
 
@@ -49,8 +49,8 @@ _No request parameters_
 
 ## Changelog
 
-- [Script History](https://github.com/NangoHQ/integration-templates/commits/main/integrations/gusto/actions/create-user.ts)
-- [Documentation History](https://github.com/NangoHQ/integration-templates/commits/main/integrations/gusto/actions/create-user.md)
+- [Script History](https://github.com/NangoHQ/integration-templates/commits/main/integrations/gusto/actions/create-employee.ts)
+- [Documentation History](https://github.com/NangoHQ/integration-templates/commits/main/integrations/gusto/actions/create-employee.md)
 
 <!-- END  GENERATED CONTENT -->
 
diff --git a/integrations/gusto/actions/create-user.ts b/integrations/gusto/actions/create-employee.ts
similarity index 75%
rename from integrations/gusto/actions/create-user.ts
rename to integrations/gusto/actions/create-employee.ts
index 3a7fcd493..c0f6e0482 100644
--- a/integrations/gusto/actions/create-user.ts
+++ b/integrations/gusto/actions/create-employee.ts
@@ -1,9 +1,9 @@
-import type { NangoAction, ProxyConfiguration, GustoCreateUser, User } from '../../models';
-import { GustoCreateUserSchema } from '../schema.js';
-import type { GustoEmployee, GustoCreateEmployee } from '../types';
+import type { NangoAction, ProxyConfiguration, GustoCreateEmployee, GustoCreateEmployeeResponse } from '../../models.js';
+import { GustoCreateEmployeeSchema } from '../schema.js';
+import type { GustoEmployee, GustoCreateEmployeeRequest } from '../types.js';
 
-export default async function runAction(nango: NangoAction, input: GustoCreateUser): Promise<User> {
-    const parsedInput = await nango.zodValidateInput({ zodSchema: GustoCreateUserSchema, input });
+export default async function runAction(nango: NangoAction, input: GustoCreateEmployee): Promise<GustoCreateEmployeeResponse> {
+    const parsedInput = await nango.zodValidateInput({ zodSchema: GustoCreateEmployeeSchema, input });
 
     const connection = await nango.getConnection();
 
@@ -15,7 +15,7 @@ export default async function runAction(nango: NangoAction, input: GustoCreateUs
         });
     }
 
-    const gustoInput: GustoCreateEmployee = {
+    const gustoInput: GustoCreateEmployeeRequest = {
         first_name: parsedInput.data.firstName,
         last_name: parsedInput.data.lastName,
         email: parsedInput.data.email
@@ -51,12 +51,12 @@ export default async function runAction(nango: NangoAction, input: GustoCreateUs
     const response = await nango.post<GustoEmployee>(config);
     const { data } = response;
 
-    const user: User = {
+    const createEmployeeResponse: GustoCreateEmployeeResponse = {
         id: data.uuid,
         firstName: data.first_name,
         lastName: data.last_name,
         email: data.email
     };
 
-    return user;
+    return createEmployeeResponse;
 }
diff --git a/integrations/gusto/actions/delete-user.md b/integrations/gusto/actions/terminate-employee.md
similarity index 67%
rename from integrations/gusto/actions/delete-user.md
rename to integrations/gusto/actions/terminate-employee.md
index 030f2b87c..dd78797f8 100644
--- a/integrations/gusto/actions/delete-user.md
+++ b/integrations/gusto/actions/terminate-employee.md
@@ -1,21 +1,21 @@
 <!-- BEGIN GENERATED CONTENT -->
-# Delete User
+# Terminate Employee
 
 ## General Information
 
-- **Description:** Deletes a user in Gusto.
+- **Description:** Terminates an employee in Gusto.
 - **Version:** 0.0.1
-- **Group:** Users
+- **Group:** Employees
 - **Scopes:** `employments:write`
 - **Endpoint Type:** Action
-- **Code:** [github.com](https://github.com/NangoHQ/integration-templates/tree/main/integrations/gusto/actions/delete-user.ts)
+- **Code:** [github.com](https://github.com/NangoHQ/integration-templates/tree/main/integrations/gusto/actions/terminate-employee.ts)
 
 
 ## Endpoint Reference
 
 ### Request Endpoint
 
-`DELETE /users`
+`DELETE /employees`
 
 ### Request Query Parameters
 
@@ -41,8 +41,8 @@ _No request parameters_
 
 ## Changelog
 
-- [Script History](https://github.com/NangoHQ/integration-templates/commits/main/integrations/gusto/actions/delete-user.ts)
-- [Documentation History](https://github.com/NangoHQ/integration-templates/commits/main/integrations/gusto/actions/delete-user.md)
+- [Script History](https://github.com/NangoHQ/integration-templates/commits/main/integrations/gusto/actions/terminate-employee.ts)
+- [Documentation History](https://github.com/NangoHQ/integration-templates/commits/main/integrations/gusto/actions/terminate-employee.md)
 
 <!-- END  GENERATED CONTENT -->
 
diff --git a/integrations/gusto/actions/delete-user.ts b/integrations/gusto/actions/terminate-employee.ts
similarity index 80%
rename from integrations/gusto/actions/delete-user.ts
rename to integrations/gusto/actions/terminate-employee.ts
index 119388a86..a4af99940 100644
--- a/integrations/gusto/actions/delete-user.ts
+++ b/integrations/gusto/actions/terminate-employee.ts
@@ -1,13 +1,13 @@
-import type { NangoAction, ProxyConfiguration, SuccessResponse, GustoDeleteUser } from '../../models';
-import type { GustoDeleteEmployee } from '../types';
+import type { NangoAction, ProxyConfiguration, SuccessResponse, GustoTerminateEmployee } from '../../models.js';
+import type { GustoDeleteEmployeeRequest } from '../types.js';
 import { idEntitySchema } from '../schema.zod.js';
 
-export default async function runAction(nango: NangoAction, input: GustoDeleteUser): Promise<SuccessResponse> {
+export default async function runAction(nango: NangoAction, input: GustoTerminateEmployee): Promise<SuccessResponse> {
     await nango.zodValidateInput({ zodSchema: idEntitySchema, input });
 
     const { id, ...rest } = input;
 
-    const gustoInput: GustoDeleteEmployee = {
+    const gustoInput: GustoDeleteEmployeeRequest = {
         effective_date: rest.effectiveDate ? new Date(rest.effectiveDate).toISOString().split('T')[0] : new Date().toISOString().split('T')[0]
     };
 
diff --git a/integrations/gusto/actions/update-employee.md b/integrations/gusto/actions/update-employee.md
new file mode 100644
index 000000000..5a68344ea
--- /dev/null
+++ b/integrations/gusto/actions/update-employee.md
@@ -0,0 +1,58 @@
+<!-- BEGIN GENERATED CONTENT -->
+# Update Employee
+
+## General Information
+
+- **Description:** Updates an employee in Gusto.
+- **Version:** 0.0.1
+- **Group:** Employees
+- **Scopes:** `employees:manage`
+- **Endpoint Type:** Action
+- **Code:** [github.com](https://github.com/NangoHQ/integration-templates/tree/main/integrations/gusto/actions/update-employee.ts)
+
+
+## Endpoint Reference
+
+### Request Endpoint
+
+`PUT /employees`
+
+### Request Query Parameters
+
+_No request parameters_
+
+### Request Body
+
+```json
+{
+  "id": "<string>",
+  "version": "<string>",
+  "firstName?": "<string>",
+  "lastName?": "<string>",
+  "email?": "<string>",
+  "middleInitial?": "<string>",
+  "preferredFirstName?": "<string>",
+  "dateOfBirth?": "<string>",
+  "ssn?": "<string>",
+  "twoPercentShareholder?": "<boolean>"
+}
+```
+
+### Request Response
+
+```json
+{
+  "id": "<string>",
+  "email": "<string>",
+  "firstName": "<string>",
+  "lastName": "<string>"
+}
+```
+
+## Changelog
+
+- [Script History](https://github.com/NangoHQ/integration-templates/commits/main/integrations/gusto/actions/update-employee.ts)
+- [Documentation History](https://github.com/NangoHQ/integration-templates/commits/main/integrations/gusto/actions/update-employee.md)
+
+<!-- END  GENERATED CONTENT -->
+
diff --git a/integrations/gusto/actions/update-employee.ts b/integrations/gusto/actions/update-employee.ts
new file mode 100644
index 000000000..a8a953cf7
--- /dev/null
+++ b/integrations/gusto/actions/update-employee.ts
@@ -0,0 +1,64 @@
+import type { NangoAction, ProxyConfiguration, GustoUpdateEmployee, GustoUpdateEmployeeResponse } from '../../models.js';
+import { GustoUpdateEmployeeSchema } from '../schema.js';
+import type { GustoEmployee, GustoUpdateEmployeeRequest } from '../types.js';
+
+export default async function runAction(nango: NangoAction, input: GustoUpdateEmployee): Promise<GustoUpdateEmployeeResponse> {
+    const parsedInput = await nango.zodValidateInput({ zodSchema: GustoUpdateEmployeeSchema, input });
+
+    const employeeId = parsedInput.data.id;
+
+    const gustoInput: GustoUpdateEmployeeRequest = {
+        version: parsedInput.data.version
+    };
+
+    if (parsedInput.data.firstName) {
+        gustoInput.first_name = parsedInput.data.firstName;
+    }
+
+    if (parsedInput.data.lastName) {
+        gustoInput.last_name = parsedInput.data.lastName;
+    }
+
+    if (parsedInput.data.email) {
+        gustoInput.email = parsedInput.data.email;
+    }
+
+    if (parsedInput.data.dateOfBirth) {
+        gustoInput.date_of_birth = parsedInput.data.dateOfBirth;
+    }
+
+    if (parsedInput.data.middleInitial) {
+        gustoInput.middle_initial = parsedInput.data.middleInitial;
+    }
+
+    if (parsedInput.data.preferredFirstName) {
+        gustoInput.preferred_first_name = parsedInput.data.preferredFirstName;
+    }
+
+    if (parsedInput.data.ssn) {
+        gustoInput.ssn = parsedInput.data.ssn;
+    }
+
+    if (parsedInput.data.twoPercentShareholder) {
+        gustoInput.two_percent_shareholder = parsedInput.data.twoPercentShareholder;
+    }
+
+    const config: ProxyConfiguration = {
+        // https://docs.gusto.com/embedded-payroll/reference/post-v1-employees
+        endpoint: `/v1/employees/${employeeId}`,
+        data: gustoInput,
+        retries: 3
+    };
+
+    const response = await nango.put<GustoEmployee>(config);
+    const { data } = response;
+
+    const createEmployeeResponse: GustoUpdateEmployeeResponse = {
+        id: data.uuid,
+        firstName: data.first_name,
+        lastName: data.last_name,
+        email: data.email
+    };
+
+    return createEmployeeResponse;
+}
diff --git a/integrations/gusto/nango.yaml b/integrations/gusto/nango.yaml
index 6a276b441..cc22ef113 100644
--- a/integrations/gusto/nango.yaml
+++ b/integrations/gusto/nango.yaml
@@ -4,40 +4,37 @@ integrations:
     # context of this repository
     ${PWD}:
         actions:
-            create-user:
-                description: Creates a user in Gusto.
-                output: User
+            create-employee:
+                description: Creates an employee in Gusto.
+                output: GustoCreateEmployeeResponse
                 endpoint:
                     method: POST
-                    path: /users
-                    group: Users
-                input: GustoCreateUser
+                    path: /employees
+                    group: Employees
+                input: GustoCreateEmployee
+                scopes:
+                    - employees:manage
+            update-employee:
+                description: Updates an employee in Gusto.
+                output: GustoUpdateEmployeeResponse
+                endpoint:
+                    method: PUT
+                    path: /employees
+                    group: Employees
+                input: GustoUpdateEmployee
                 scopes:
                     - employees:manage
-            delete-user:
-                description: Deletes a user in Gusto.
+            terminate-employee:
+                description: Terminates an employee in Gusto.
                 endpoint:
                     method: DELETE
-                    path: /users
-                    group: Users
+                    path: /employees
+                    group: Employees
                 output: SuccessResponse
-                input: GustoDeleteUser
+                input: GustoTerminateEmployee
                 scopes:
                     - employments:write
         syncs:
-            users:
-                runs: every day
-                description: |
-                    Fetches a list of users from Gusto.
-                output: User
-                track_deletes: true
-                sync_type: full
-                endpoint:
-                    method: GET
-                    path: /users
-                    group: Users
-                scopes:
-                    - employees:read
             employees:
                 runs: every 5m
                 description: Fetches all employees from Gusto
@@ -65,27 +62,39 @@ models:
     IdEntity:
         id: string
 
-    # User
-    User:
-        id: string
-        email: string
+    # Employee
+    GustoCreateEmployee:
         firstName: string
         lastName: string
+        email: string
+        middleInitial?: string
+        preferredFirstName?: string
+        dateOfBirth: string
+        ssn?: string
+        selfOnboarding?: boolean
 
-    CreateUser:
+    GustoCreateEmployeeResponse:
+        id: string
+        email: string
         firstName: string
         lastName: string
-        email: string
 
-    GustoCreateUser:
-        __extends: CreateUser
+    GustoUpdateEmployee:
+        __extends: IdEntity
+        version: string
+        firstName?: string
+        lastName?: string
+        email?: string
         middleInitial?: string
         preferredFirstName?: string
-        dateOfBirth: string
+        dateOfBirth?: string
         ssn?: string
-        selfOnboarding?: boolean
+        twoPercentShareholder?: boolean
+
+    GustoUpdateEmployeeResponse:
+        __extends: GustoCreateEmployeeResponse
 
-    GustoDeleteUser:
+    GustoTerminateEmployee:
         __extends: IdEntity
         effectiveDate?: string
         runTerminationPayroll?: boolean
diff --git a/integrations/gusto/schema.ts b/integrations/gusto/schema.ts
index f56187923..670b6ddd2 100644
--- a/integrations/gusto/schema.ts
+++ b/integrations/gusto/schema.ts
@@ -1,7 +1,7 @@
 import { z } from 'zod';
-import { gustoCreateUserSchema as GustoCreate } from './schema.zod.js';
+import { gustoCreateEmployeeSchema as GustoCreate, gustoUpdateEmployeeSchema as GustoUpdate } from './schema.zod.js';
 
-const FormatteDate = z
+const FormattedDate = z
     .string()
     .optional()
     .refine(
@@ -22,6 +22,10 @@ const FormatteDate = z
         return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
     });
 
-export const GustoCreateUserSchema = GustoCreate.extend({
-    dateOfBirth: FormatteDate
+export const GustoCreateEmployeeSchema = GustoCreate.extend({
+    dateOfBirth: FormattedDate
+});
+
+export const GustoUpdateEmployeeSchema = GustoUpdate.extend({
+    dateOfBirth: FormattedDate
 });
diff --git a/integrations/gusto/schema.zod.ts b/integrations/gusto/schema.zod.ts
index cfa6eb93f..8cb975d7e 100644
--- a/integrations/gusto/schema.zod.ts
+++ b/integrations/gusto/schema.zod.ts
@@ -9,32 +9,147 @@ export const idEntitySchema = z.object({
     id: z.string()
 });
 
-export const userSchema = z.object({
-    id: z.string(),
-    email: z.string(),
+export const gustoCreateEmployeeSchema = z.object({
     firstName: z.string(),
-    lastName: z.string()
+    lastName: z.string(),
+    email: z.string(),
+    middleInitial: z.string().optional(),
+    preferredFirstName: z.string().optional(),
+    dateOfBirth: z.string(),
+    ssn: z.string().optional(),
+    selfOnboarding: z.boolean().optional()
 });
 
-export const createUserSchema = z.object({
+export const gustoCreateEmployeeResponseSchema = z.object({
+    id: z.string(),
+    email: z.string(),
     firstName: z.string(),
-    lastName: z.string(),
-    email: z.string()
+    lastName: z.string()
 });
 
-export const gustoCreateUserSchema = z.object({
-    firstName: z.string(),
-    lastName: z.string(),
-    email: z.string(),
+export const gustoUpdateEmployeeSchema = z.object({
+    id: z.string(),
+    version: z.string(),
+    firstName: z.string().optional(),
+    lastName: z.string().optional(),
+    email: z.string().optional(),
     middleInitial: z.string().optional(),
     preferredFirstName: z.string().optional(),
-    dateOfBirth: z.string(),
+    dateOfBirth: z.string().optional(),
     ssn: z.string().optional(),
-    selfOnboarding: z.boolean().optional()
+    twoPercentShareholder: z.boolean().optional()
+});
+
+export const gustoUpdateEmployeeResponseSchema = z.object({
+    id: z.string(),
+    email: z.string(),
+    firstName: z.string(),
+    lastName: z.string()
 });
 
-export const gustoDeleteUserSchema = z.object({
+export const gustoTerminateEmployeeSchema = z.object({
     id: z.string(),
     effectiveDate: z.string().optional(),
     runTerminationPayroll: z.boolean().optional()
 });
+
+export const gustoEmployeeSchema = z.object({
+    id: z.string(),
+    uuid: z.string(),
+    first_name: z.string(),
+    last_name: z.string(),
+    email: z.string(),
+    work_email: z.string(),
+    phone: z.string(),
+    department: z.string(),
+    department_uuid: z.string(),
+    manager_uuid: z.string(),
+    version: z.string(),
+    terminated: z.boolean(),
+    onboarded: z.boolean(),
+    onboarding_status: z.string(),
+    date_of_birth: z.string(),
+    has_ssn: z.boolean(),
+    custom_fields: z.string(),
+    jobs: z.array(
+        z.object({
+            id: z.string(),
+            title: z.string(),
+            hire_date: z.string(),
+            payment_unit: z.string(),
+            primary: z.boolean()
+        })
+    )
+});
+
+export const addressSchema = z.object({
+    street: z.string().optional(),
+    city: z.string().optional(),
+    state: z.string().optional(),
+    country: z.string().optional(),
+    postalCode: z.string().optional(),
+    type: z.union([z.literal('WORK'), z.literal('HOME')])
+});
+
+export const phoneSchema = z.object({
+    type: z.union([z.literal('WORK'), z.literal('HOME'), z.literal('MOBILE')]),
+    number: z.string()
+});
+
+export const emailSchema = z.object({
+    type: z.union([z.literal('WORK'), z.literal('PERSONAL')]),
+    address: z.string()
+});
+
+export const standardEmployeeSchema = z.object({
+    id: z.string(),
+    firstName: z.string(),
+    lastName: z.string(),
+    email: z.string(),
+    displayName: z.string(),
+    employeeNumber: z.string().optional(),
+    title: z.string().optional(),
+    department: z.object({
+        id: z.string(),
+        name: z.string()
+    }),
+    employmentType: z.union([
+        z.literal('FULL_TIME'),
+        z.literal('PART_TIME'),
+        z.literal('CONTRACTOR'),
+        z.literal('INTERN'),
+        z.literal('TEMPORARY'),
+        z.literal('OTHER')
+    ]),
+    employmentStatus: z.union([z.literal('ACTIVE'), z.literal('TERMINATED'), z.literal('ON_LEAVE'), z.literal('SUSPENDED'), z.literal('PENDING')]),
+    startDate: z.string(),
+    terminationDate: z.string().optional(),
+    manager: z
+        .object({
+            id: z.string().optional(),
+            firstName: z.string().optional(),
+            lastName: z.string().optional(),
+            email: z.string().optional()
+        })
+        .optional(),
+    workLocation: z.object({
+        name: z.string(),
+        type: z.union([z.literal('OFFICE'), z.literal('REMOTE'), z.literal('HYBRID')]),
+        primaryAddress: z
+            .object({
+                street: z.string().optional(),
+                city: z.string().optional(),
+                state: z.string().optional(),
+                country: z.string().optional(),
+                postalCode: z.string().optional(),
+                type: z.union([z.literal('WORK'), z.literal('HOME')])
+            })
+            .optional()
+    }),
+    addresses: z.array(addressSchema).optional(),
+    phones: z.array(phoneSchema).optional(),
+    emails: z.array(emailSchema).optional(),
+    providerSpecific: z.record(z.any()),
+    createdAt: z.string(),
+    updatedAt: z.string()
+});
diff --git a/integrations/gusto/syncs/users.md b/integrations/gusto/syncs/users.md
deleted file mode 100644
index 89329d657..000000000
--- a/integrations/gusto/syncs/users.md
+++ /dev/null
@@ -1,50 +0,0 @@
-<!-- BEGIN GENERATED CONTENT -->
-# Users
-
-## General Information
-
-- **Description:** Fetches a list of users from Gusto.
-
-- **Version:** 0.0.1
-- **Group:** Users
-- **Scopes:** `employees:read`
-- **Endpoint Type:** Sync
-- **Code:** [github.com](https://github.com/NangoHQ/integration-templates/tree/main/integrations/gusto/syncs/users.ts)
-
-
-## Endpoint Reference
-
-### Request Endpoint
-
-`GET /users`
-
-### Request Query Parameters
-
-- **modified_after:** `(optional, string)` A timestamp (e.g., `2023-05-31T11:46:13.390Z`) used to fetch records modified after this date and time. If not provided, all records are returned. The modified_after parameter is less precise than cursor, as multiple records may share the same modification timestamp.
-- **limit:** `(optional, integer)` The maximum number of records to return per page. Defaults to 100.
-- **cursor:** `(optional, string)` A marker used to fetch records modified after a specific point in time.If not provided, all records are returned.Each record includes a cursor value found in _nango_metadata.cursor.Save the cursor from the last record retrieved to track your sync progress.Use the cursor parameter together with the limit parameter to paginate through records.The cursor is more precise than modified_after, as it can differentiate between records with the same modification timestamp.
-- **filter:** `(optional, added | updated | deleted)` Filter to only show results that have been added or updated or deleted.
-- **ids:** `(optional, string[])` An array of string containing a list of your records IDs. The list will be filtered to include only the records with a matching ID.
-
-### Request Body
-
-_No request body_
-
-### Request Response
-
-```json
-{
-  "id": "<string>",
-  "email": "<string>",
-  "firstName": "<string>",
-  "lastName": "<string>"
-}
-```
-
-## Changelog
-
-- [Script History](https://github.com/NangoHQ/integration-templates/commits/main/integrations/gusto/syncs/users.ts)
-- [Documentation History](https://github.com/NangoHQ/integration-templates/commits/main/integrations/gusto/syncs/users.md)
-
-<!-- END  GENERATED CONTENT -->
-
diff --git a/integrations/gusto/syncs/users.ts b/integrations/gusto/syncs/users.ts
deleted file mode 100644
index 7235348f2..000000000
--- a/integrations/gusto/syncs/users.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import type { NangoSync, ProxyConfiguration, User } from '../../models';
-import type { EmployeeResponse } from '../types';
-
-export default async function fetchData(nango: NangoSync) {
-    const connection = await nango.getConnection();
-
-    const companyUuid = connection.connection_config['companyUuid'];
-
-    if (!companyUuid) {
-        throw new nango.ActionError({
-            message: 'Company UUID is missing from the connection configuration'
-        });
-    }
-
-    const config: ProxyConfiguration = {
-        // https://docs.gusto.com/embedded-payroll/reference/get-v1-companies-company_id-employees
-        endpoint: `/v1/companies/${companyUuid}/employees`,
-        paginate: {
-            type: 'offset',
-            offset_name_in_request: 'page',
-            response_path: '',
-            limit_name_in_request: 'per'
-        }
-    };
-
-    for await (const gUsers of nango.paginate<EmployeeResponse>(config)) {
-        const users: User[] = gUsers.map((gUser: EmployeeResponse) => {
-            return {
-                id: gUser.uuid,
-                firstName: gUser.first_name,
-                lastName: gUser.last_name,
-                email: gUser.email
-            };
-        });
-
-        await nango.batchSave(users, 'User');
-    }
-}
diff --git a/integrations/gusto/tests/gusto-create-user.test.ts b/integrations/gusto/tests/gusto-create-user.test.ts
index 221924d3b..f58443a38 100644
--- a/integrations/gusto/tests/gusto-create-user.test.ts
+++ b/integrations/gusto/tests/gusto-create-user.test.ts
@@ -1,6 +1,6 @@
 import { vi, expect, it, describe } from 'vitest';
 
-import runAction from '../actions/create-user.js';
+import runAction from '../actions/create-employee.js';
 
 describe('gusto create-user tests', () => {
     const nangoMock = new global.vitest.NangoActionMock({
diff --git a/integrations/gusto/tests/gusto-delete-user.test.ts b/integrations/gusto/tests/gusto-delete-user.test.ts
index ed4bddc14..5478c5ae9 100644
--- a/integrations/gusto/tests/gusto-delete-user.test.ts
+++ b/integrations/gusto/tests/gusto-delete-user.test.ts
@@ -1,6 +1,6 @@
 import { vi, expect, it, describe } from 'vitest';
 
-import runAction from '../actions/delete-user.js';
+import runAction from '../actions/terminate-employee.js';
 
 describe('gusto delete-user tests', () => {
     const nangoMock = new global.vitest.NangoActionMock({
diff --git a/integrations/gusto/tests/gusto-demo-create-user.test.ts b/integrations/gusto/tests/gusto-demo-create-user.test.ts
index 69e3b47c0..35ec7ce7d 100644
--- a/integrations/gusto/tests/gusto-demo-create-user.test.ts
+++ b/integrations/gusto/tests/gusto-demo-create-user.test.ts
@@ -1,6 +1,6 @@
 import { vi, expect, it, describe } from 'vitest';
 
-import runAction from '../actions/create-user.js';
+import runAction from '../actions/create-employee.js';
 
 describe('gusto-demo create-user tests', () => {
     const nangoMock = new global.vitest.NangoActionMock({
diff --git a/integrations/gusto/tests/gusto-demo-delete-user.test.ts b/integrations/gusto/tests/gusto-demo-delete-user.test.ts
index acd96c6cd..096832de5 100644
--- a/integrations/gusto/tests/gusto-demo-delete-user.test.ts
+++ b/integrations/gusto/tests/gusto-demo-delete-user.test.ts
@@ -1,6 +1,6 @@
 import { vi, expect, it, describe } from 'vitest';
 
-import runAction from '../actions/delete-user.js';
+import runAction from '../actions/terminate-employee.js';
 
 describe('gusto-demo delete-user tests', () => {
     const nangoMock = new global.vitest.NangoActionMock({
diff --git a/integrations/gusto/tests/gusto-demo-users.test.ts b/integrations/gusto/tests/gusto-demo-users.test.ts
deleted file mode 100644
index 18364c064..000000000
--- a/integrations/gusto/tests/gusto-demo-users.test.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { vi, expect, it, describe } from 'vitest';
-
-import fetchData from '../syncs/users.js';
-
-describe('gusto-demo users tests', () => {
-    const nangoMock = new global.vitest.NangoSyncMock({
-        dirname: __dirname,
-        name: 'users',
-        Model: 'User'
-    });
-
-    const models = 'User'.split(',');
-    const batchSaveSpy = vi.spyOn(nangoMock, 'batchSave');
-
-    it('should get, map correctly the data and batchSave the result', async () => {
-        await fetchData(nangoMock);
-
-        for (const model of models) {
-            const batchSaveData = await nangoMock.getBatchSaveData(model);
-
-            const totalCalls = batchSaveSpy.mock.calls.length;
-
-            if (totalCalls > models.length) {
-                const splitSize = Math.ceil(batchSaveData.length / totalCalls);
-
-                const splitBatchSaveData = [];
-                for (let i = 0; i < totalCalls; i++) {
-                    const chunk = batchSaveData.slice(i * splitSize, (i + 1) * splitSize);
-                    splitBatchSaveData.push(chunk);
-                }
-
-                splitBatchSaveData.forEach((data, index) => {
-                    // @ts-ignore
-                    expect(batchSaveSpy?.mock.calls[index][0]).toEqual(data);
-                });
-            } else {
-                expect(nangoMock.batchSave).toHaveBeenCalledWith(batchSaveData, model);
-            }
-        }
-    });
-
-    it('should get, map correctly the data and batchDelete the result', async () => {
-        await fetchData(nangoMock);
-
-        for (const model of models) {
-            const batchDeleteData = await nangoMock.getBatchDeleteData(model);
-            if (batchDeleteData && batchDeleteData.length > 0) {
-                expect(nangoMock.batchDelete).toHaveBeenCalledWith(batchDeleteData, model);
-            }
-        }
-    });
-});
diff --git a/integrations/gusto/tests/gusto-users.test.ts b/integrations/gusto/tests/gusto-users.test.ts
deleted file mode 100644
index 9348f4b10..000000000
--- a/integrations/gusto/tests/gusto-users.test.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { vi, expect, it, describe } from 'vitest';
-
-import fetchData from '../syncs/users.js';
-
-describe('gusto users tests', () => {
-    const nangoMock = new global.vitest.NangoSyncMock({
-        dirname: __dirname,
-        name: 'users',
-        Model: 'User'
-    });
-
-    const models = 'User'.split(',');
-    const batchSaveSpy = vi.spyOn(nangoMock, 'batchSave');
-
-    it('should get, map correctly the data and batchSave the result', async () => {
-        await fetchData(nangoMock);
-
-        for (const model of models) {
-            const expectedBatchSaveData = await nangoMock.getBatchSaveData(model);
-
-            const spiedData = batchSaveSpy.mock.calls.flatMap((call) => {
-                if (call[1] === model) {
-                    return call[0];
-                }
-
-                return [];
-            });
-
-            const spied = JSON.parse(JSON.stringify(spiedData));
-
-            expect(spied).toStrictEqual(expectedBatchSaveData);
-        }
-    });
-
-    it('should get, map correctly the data and batchDelete the result', async () => {
-        await fetchData(nangoMock);
-
-        for (const model of models) {
-            const batchDeleteData = await nangoMock.getBatchDeleteData(model);
-            if (batchDeleteData && batchDeleteData.length > 0) {
-                expect(nangoMock.batchDelete).toHaveBeenCalledWith(batchDeleteData, model);
-            }
-        }
-    });
-});
diff --git a/integrations/gusto/types.ts b/integrations/gusto/types.ts
index 89c55e805..5c2263a45 100644
--- a/integrations/gusto/types.ts
+++ b/integrations/gusto/types.ts
@@ -1,4 +1,4 @@
-export interface GustoCreateEmployee {
+export interface GustoCreateEmployeeRequest {
     first_name: string;
     middle_initial?: string;
     last_name: string;
@@ -9,7 +9,20 @@ export interface GustoCreateEmployee {
     self_onboarding?: boolean;
 }
 
-export interface GustoDeleteEmployee {
+export interface GustoUpdateEmployeeRequest {
+    version: string;
+    first_name?: string;
+    middle_initial?: string;
+    last_name?: string;
+    email?: string;
+    date_of_birth?: string;
+    preferred_first_name?: string;
+    ssn?: string;
+    self_onboarding?: boolean;
+    two_percent_shareholder?: boolean;
+}
+
+export interface GustoDeleteEmployeeRequest {
     effective_date?: string | undefined;
     run_termination_payroll?: boolean;
 }


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 9**

<details>
<summary>🔭 Outside diff range comments (1)</summary><blockquote>

<details>
<summary>integrations/gusto/.nango/schema.json (1)</summary><blockquote>

`74-110`: _🛠️ Refactor suggestion_

**`version` should be numeric, not free-form text**

`version` is currently defined as a string.  In Gusto’s API the version field increments monotonically (1, 2, 3…), so exposing it as `"type": "integer"` (or at least `"number"`) prevents accidental non-numeric values and simplifies client arithmetic (e.g. `version + 1` during optimistic concurrency).

```diff
-                "version": {
-                    "type": "string"
+                "version": {
+                    "type": "integer",
+                    "minimum": 1
                 },
```
Aligning the schema with the provider contract reduces runtime failures.

</blockquote></details>

</blockquote></details>

<details>
<summary>♻️ Duplicate comments (3)</summary><blockquote>

<details>
<summary>flows.yaml (3)</summary><blockquote>

`6902-6935`: **Mirror path and sync fixes in `gusto-demo`.**

The demo integration’s `update-employee` and `terminate-employee` actions likewise need an `{id}` placeholder in the endpoint paths (e.g. `/employees/{{ input.id }}`), and its `employees` sync should declare the corresponding action to execute. Apply the same corrections you made in the main flow.

---

`6959-6963`: **Duplicate schema verification for demo create.**

Echoing the main integration’s schema review: confirm that `GustoCreateEmployee` in the demo flow includes all required fields per the Gusto API and properly marks optional ones.

---

`6969-6993`: **Duplicate schema verification for demo responses and updates.**

As above, ensure that the demo’s response and update models (`GustoCreateEmployeeResponse`, `GustoUpdateEmployee`, `GustoUpdateEmployeeResponse`, `GustoTerminateEmployee`) accurately reflect Gusto’s API payload structure and data types.

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (7)</summary><blockquote>

<details>
<summary>integrations/gusto/actions/update-employee.md (1)</summary><blockquote>

`22-22`: **Fix markdown formatting**

The line `_No request parameters_` uses emphasis instead of plain text, which violates markdown linting rules (MD036).

```diff
-_No request parameters_
+No request parameters
```

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.17.2)</summary>

22-22: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)

</details>

</details>

</blockquote></details>
<details>
<summary>integrations/gusto/actions/update-employee.ts (2)</summary><blockquote>

`46-51`: **Consider adjusting retry count to match guidelines.**

The API documentation link is properly included. However, the retry count is set to 3 while the coding guidelines recommend a default of 10 for proxy calls.

```diff
const config: ProxyConfiguration = {
    // https://docs.gusto.com/embedded-payroll/reference/post-v1-employees
    endpoint: `/v1/employees/${employeeId}`,
    data: gustoInput,
-    retries: 3
+    retries: 10
};
```

---

`56-61`: **Variable name doesn't match the action being performed.**

The variable `createEmployeeResponse` is used in an update action, which may cause confusion.

```diff
-const createEmployeeResponse: GustoUpdateEmployeeResponse = {
+const updateEmployeeResponse: GustoUpdateEmployeeResponse = {
    id: data.uuid,
    firstName: data.first_name,
    lastName: data.last_name,
    email: data.email
};

-return createEmployeeResponse;
+return updateEmployeeResponse;
```

</blockquote></details>
<details>
<summary>integrations/gusto/actions/create-employee.ts (1)</summary><blockquote>

`44-49`: **Consider adjusting retry count to match guidelines.**

The API documentation link is properly included. However, the retry count is set to 3 while the coding guidelines recommend a default of 10 for proxy calls.

```diff
const config: ProxyConfiguration = {
    // https://docs.gusto.com/embedded-payroll/reference/post-v1-employees
    endpoint: `/v1/companies/${companyUuid}/employees`,
    data: gustoInput,
-    retries: 3
+    retries: 10
};
```

</blockquote></details>
<details>
<summary>integrations/gusto/.nango/schema.json (1)</summary><blockquote>

`130-145`: **Enforce ISO date for `effectiveDate`**

For `GustoTerminateEmployee`, `effectiveDate` is also a plain string.  Consider adding a date format:

```diff
-                "effectiveDate": {
-                    "type": "string"
+                "effectiveDate": {
+                    "type": "string",
+                    "format": "date"
                 },
```
This mirrors the stricter validation added to `dateOfBirth`.

</blockquote></details>
<details>
<summary>integrations/gusto/.nango/schema.ts (1)</summary><blockquote>

`58-76`: **Expose `custom_fields` as a structured record**

`custom_fields` is typed as `string`, losing any shape information and forcing callers to JSON-parse manually.  If the field is a JSON object in the API response, model it accordingly:

```diff
-    custom_fields: string;
+    custom_fields: Record<string, unknown>;
```

Doing so lets consumers access keys safely and propagates correct typings into mapping code.

</blockquote></details>
<details>
<summary>integrations/gusto/schema.zod.ts (1)</summary><blockquote>

`50-55`: **Strengthen `effectiveDate` validation**

After adding the `format` hint in JSON-Schema, refine the Zod validator:

```diff
-    effectiveDate: z.string().optional(),
+    effectiveDate: z.string().date().optional(),
```

`z.string().date()` (available since zod 3.22) guarantees ISO-8601 conformity.

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: .coderabbit.yaml**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 508d940eda0321c9ad5d2cd96c2cf5dda742e341 and c54d2f0bb218eca854091d25cc5da3c757cee9ac.

</details>

<details>
<summary>📒 Files selected for processing (19)</summary>

* `flows.yaml` (6 hunks)
* `integrations/gusto/.nango/schema.json` (3 hunks)
* `integrations/gusto/.nango/schema.ts` (2 hunks)
* `integrations/gusto/actions/create-employee.md` (2 hunks)
* `integrations/gusto/actions/create-employee.ts` (3 hunks)
* `integrations/gusto/actions/terminate-employee.md` (2 hunks)
* `integrations/gusto/actions/terminate-employee.ts` (1 hunks)
* `integrations/gusto/actions/update-employee.md` (1 hunks)
* `integrations/gusto/actions/update-employee.ts` (1 hunks)
* `integrations/gusto/nango.yaml` (2 hunks)
* `integrations/gusto/schema.ts` (2 hunks)
* `integrations/gusto/schema.zod.ts` (1 hunks)
* `integrations/gusto/syncs/users.md` (0 hunks)
* `integrations/gusto/syncs/users.ts` (0 hunks)
* `integrations/gusto/tests/gusto-create-user.test.ts` (1 hunks)
* `integrations/gusto/tests/gusto-delete-user.test.ts` (1 hunks)
* `integrations/gusto/tests/gusto-demo-create-user.test.ts` (1 hunks)
* `integrations/gusto/tests/gusto-demo-delete-user.test.ts` (1 hunks)
* `integrations/gusto/types.ts` (2 hunks)

</details>

<details>
<summary>💤 Files with no reviewable changes (2)</summary>

* integrations/gusto/syncs/users.ts
* integrations/gusto/syncs/users.md

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>📓 Path-based instructions (2)</summary>

<details>
<summary>`integrations/**/**.ts`: - Use TypeScript best practices and ensure typings are strictly defined.
- Use comments to explain logic and link to external API documentation.
- Place en...</summary>

> `integrations/**/**.ts`: - Use TypeScript best practices and ensure typings are strictly defined.
> - Use comments to explain logic and link to external API documentation.
> - Place endpoint URLs as comments above API requests.
> - Avoid modifying arguments and prefer returning new values.
> - Create a `types.ts` file containing typed third-party API responses.
> - Proxy calls should use retries (default: `10`).
> - Use `await nango.log()` instead of `console.log` for logging.
> - Use the `params` property in proxy calls instead of appending params onto the endpoint.
> - Use `nango.paginate` wherever possible for pagination.
> - Always use `ProxyConfiguration` for proxy request configurations.
> - Validate inputs/outputs using `zod`.
> - Ensure date inputs are valid and converted using `new Date()` to the provider's expected format.
> # Syncs
> - The `fetchData` function must be the default export and placed at the top.
> - Always paginate requests to ensure all records are retrieved.
> - Avoid parallel requests to maintain the retry policy and prevent rate limits.
> - Mapping logic should be in a dedicated function.
> - Shared mapping logic should be stored in a `mappers` directory.
> - Mapper files should follow the `mappers/to-{entity}.ts` naming convention.
> - Avoid type casting and rely on TypeScript's type checking.
> - If the sync is incremental, use `nango.lastSyncDate`.
> 
> # Actions
> - The `runAction` function must be the default export and placed at the top.
> - Use `ActionError` only for specific error messages, otherwise rely on script failure.
> 
> Example:
> ```typescript
> throw new nango.ActionError<ActionErrorResponse>({
>   message: 'Missing some parameter that will prevent the action from successfully running'
> });
> ```
> 
> # TypeScript Development Guidelines
> 
> ## Syncs
> - `fetchData` must be the default export at the top of the file
> - Always paginate requests to retrieve all records
> - Avoid parallelizing requests (defeats retry policy and rate limiting)
> - Do not wrap syncs in try-catch blocks (Nango handles error reporting)
> - Use dedicated mapper functions for data transformation:
> - Place shared mappers in a `mappers` directory
> - Name files as `mappers/to-${entity}` (e.g., `mappers/to-employee.ts`)
> - Avoid type casting to leverage TypeScript benefits:
> - For incremental syncs, use `nango.lastSyncDate`
> 
> ## Actions
> - `runAction` must be the default export at the top of the file
> - Only use `ActionError` for specific error messages:
> - Always return objects, not arrays
> - Always define API calls using a typed `ProxyConfiguration` object with retries set to 3:
> - When implementing pagination in actions, always return a cursor-based response to allow users to paginate through results:

- `integrations/gusto/tests/gusto-delete-user.test.ts`
- `integrations/gusto/actions/terminate-employee.ts`
- `integrations/gusto/tests/gusto-demo-delete-user.test.ts`
- `integrations/gusto/tests/gusto-demo-create-user.test.ts`
- `integrations/gusto/tests/gusto-create-user.test.ts`
- `integrations/gusto/actions/update-employee.ts`
- `integrations/gusto/actions/create-employee.ts`
- `integrations/gusto/types.ts`
- `integrations/gusto/schema.ts`
- `integrations/gusto/schema.zod.ts`

</details>
<details>
<summary>`integrations/**/nango.yaml`: - If `sync_type: full`, then the sync should also have `track_deletes: true`.
- If the sync requires metadata, set `auto_start: false` and document th...</summary>

> `integrations/**/nango.yaml`: - If `sync_type: full`, then the sync should also have `track_deletes: true`.
> - If the sync requires metadata, set `auto_start: false` and document the metadata as an input in `nango.yaml`.
> - Scopes should be explicitly documented.
> 
> - If `sync_type: full`, then the sync should also have `track_deletes: true`
> - If the sync requires metadata, then the sync should be set to `auto_start: false`. The metadata should be documented as an input in the nango.yaml
> - Scopes should be documented
> - For optional properties in models, use the `?` suffix after the property name
> - Endpoints should be concise and simple, not necessarily reflecting the exact third-party API path
> - Model names and endpoint paths should not be duplicated within an integration
> - When adding a new integration, take care to not remove unrelated entries in the nango.yaml
> - For enum values in models, do not use quotes around the values

- `integrations/gusto/nango.yaml`

</details>

</details><details>
<summary>🧬 Code Graph Analysis (2)</summary>

<details>
<summary>integrations/gusto/actions/terminate-employee.ts (3)</summary><blockquote>

<details>
<summary>integrations/gusto/.nango/schema.ts (2)</summary>

* `GustoTerminateEmployee` (52-56)
* `SuccessResponse` (6-8)

</details>
<details>
<summary>integrations/gusto/schema.zod.ts (1)</summary>

* `idEntitySchema` (8-10)

</details>
<details>
<summary>integrations/gusto/types.ts (1)</summary>

* `GustoDeleteEmployeeRequest` (25-28)

</details>

</blockquote></details>
<details>
<summary>integrations/gusto/actions/update-employee.ts (3)</summary><blockquote>

<details>
<summary>integrations/gusto/.nango/schema.ts (3)</summary>

* `GustoUpdateEmployee` (32-43)
* `GustoUpdateEmployeeResponse` (45-50)
* `GustoEmployee` (58-77)

</details>
<details>
<summary>integrations/gusto/schema.ts (1)</summary>

* `GustoUpdateEmployeeSchema` (29-31)

</details>
<details>
<summary>integrations/gusto/types.ts (2)</summary>

* `GustoUpdateEmployeeRequest` (12-23)
* `GustoEmployee` (30-56)

</details>

</blockquote></details>

</details><details>
<summary>🪛 markdownlint-cli2 (0.17.2)</summary>

<details>
<summary>integrations/gusto/actions/update-employee.md</summary>

22-22: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)

</details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (1)</summary>

* GitHub Check: flow-compilation

</details>

<details>
<summary>🔇 Additional comments (31)</summary><blockquote>

<details>
<summary>integrations/gusto/actions/create-employee.md (1)</summary>

`2-11`: **Documentation looks good**

The documentation correctly reflects the changes from "User" to "Employee" terminology and includes the proper endpoint and group.

</details>
<details>
<summary>integrations/gusto/actions/terminate-employee.ts (4)</summary>

`1-2`: **Import types updated correctly**

The import statements have been properly updated to reflect the terminology change from "user" to "employee".

---

`5-5`: **Function signature properly updated**

The input type has been correctly updated from `GustoDeleteUser` to `GustoTerminateEmployee` to match the renamed schema.

---

`10-10`: **Request object type updated properly**

The request object type has been correctly updated to `GustoDeleteEmployeeRequest`.

---

`19-20`: <details>
<summary>❓ Verification inconclusive</summary>

**Document reference doesn't match request method**

The comment references a POST endpoint while the code uses POST method, but the documentation in the MD file mentions this as a DELETE endpoint. Confirm and standardize this across all documentation.

---

🏁 Script executed:

```shell
#!/bin/bash
# Check the Gusto API documentation to verify the termination endpoint method
curl -s "https://docs.gusto.com/embedded-payroll/reference/post-v1-employees-employee_id-terminations" | grep -A 5 "POST\|DELETE"

# Another option is to check if there's information in the repository README or docs
find . -name "README.md" -o -name "*.md" | xargs grep -l "termination" | xargs grep -A 5 "POST\|DELETE"
```

Length of output: 65767

---



</details>

**Verify terminate-employee HTTP method**

I wasn’t able to find any in-repo docs describing this as a DELETE endpoint—our code currently does:

```ts
// https://docs.gusto.com/embedded-payroll/reference/post-v1-employees-employee_id-terminations
endpoint: `/v1/employees/${input.id}/terminations`,
```

Please confirm with the official Gusto API reference that:

- The termination endpoint is indeed a POST (to create a termination) and not DELETE.
- The URL in the comment matches the correct “post-…-terminations” or “delete-…-terminations” slug.
- Any other usage in the repo is updated to reflect the right method.

</details>
<details>
<summary>integrations/gusto/schema.ts (3)</summary>

`2-2`: **Clear import renaming with appropriate aliases.**

The renaming of imports to `GustoCreate` and `GustoUpdate` improves readability while maintaining access to the base schemas needed for extension.

---

`4-23`: **Date formatting schema implementation is correct.**

This schema properly validates and transforms date inputs to the `YYYY-M-D` format required by the Gusto API. The validation ensures that only valid dates are accepted, and the transformation correctly handles the month indexing.

---

`25-31`: **Good schema extension pattern for employee-focused schemas.**

The schemas appropriately extend the base schemas with the additional `dateOfBirth` field using the `FormattedDate` schema for validation and transformation.

</details>
<details>
<summary>integrations/gusto/actions/update-employee.ts (3)</summary>

`1-4`: **Imports are well-structured with proper types.**

The imports correctly reference the necessary types and schemas for the update employee action.

---

`5-7`: **Function signature and input validation follow best practices.**

The default export async function with Zod validation follows the recommended pattern for Nango actions.

---

`10-44`: **Well-structured request payload construction.**

The code properly transforms camelCase TypeScript properties to snake_case API fields, only including properties that are provided in the input.

</details>
<details>
<summary>integrations/gusto/actions/create-employee.ts (4)</summary>

`1-3`: **Imports correctly updated for employee-focused approach.**

The imports have been properly updated to reference employee types instead of user types.

---

`5-6`: **Function signature updated to match employee types.**

The function signature has been correctly updated to use `GustoCreateEmployee` and `GustoCreateEmployeeResponse` types.

---

`18-22`: **Request payload property assignment is correct.**

The core request fields are properly assigned from the validated input.

---

`54-61`: **Response structure correctly returns employee information.**

The response object is properly constructed with the required fields transformed from snake_case to camelCase.

</details>
<details>
<summary>integrations/gusto/types.ts (3)</summary>

`1-10`: **Request interface properly defined for creating employees.**

The `GustoCreateEmployeeRequest` interface correctly defines the required and optional fields for creating an employee with the Gusto API.

---

`12-23`: **Update employee request interface with version requirement.**

The `GustoUpdateEmployeeRequest` interface correctly includes a required `version` field and makes all other fields optional, which is appropriate for an update operation.

---

`25-28`: **Delete employee request interface properly defined.**

The `GustoDeleteEmployeeRequest` interface includes the necessary fields for terminating an employee with optional date and payroll settings.

</details>
<details>
<summary>integrations/gusto/schema.zod.ts (1)</summary>

`30-41`: **Keep Zod schema consistent with proposed numeric `version`**

If you adopt the numeric change, mirror it here:

```diff
-    version: z.string(),
+    version: z.number().int().positive(),
```
Consistency between TS, Zod, and JSON-Schema prevents silent drift.

</details>
<details>
<summary>flows.yaml (2)</summary>

`6792-6795`: **Validate create-employee input schema against API requirements.**

The `GustoCreateEmployee` model only includes `firstName`, `lastName`, and `email`. Confirm whether additional fields (e.g., `hireDate`, `employeeType`) are required or optional in the Create Employee API, and update the schema definitions and field annotations as needed.

---

`6801-6824`: **Verify response and update schemas with official payloads.**

Please ensure the `GustoCreateEmployeeResponse`, `GustoUpdateEmployee`, `GustoUpdateEmployeeResponse`, and `GustoTerminateEmployee` models exactly match Gusto’s API—pay special attention to field names, types (e.g., is `version` a string?), and optional flags (`ssn`, `twoPercentShareholder`). Mismatches here can lead to runtime errors or dropped data.

</details>
<details>
<summary>integrations/gusto/nango.yaml (10)</summary>

`7-16`: **create-employee action configuration looks correct**  
The `create-employee` action defines `input`, `output`, `endpoint`, and `scopes` in line with guidelines.

---

`17-26`: **Confirm path parameterization for update-employee**  
The PUT `/employees` endpoint may require the employee ID in the URL (e.g. `/employees/{id}`) rather than just in the request body. Verify against Gusto’s API spec and adjust the `path` accordingly if needed.

---

`27-36`: **Confirm path parameterization and scopes for terminate-employee**  
DELETE operations typically include an identifier in the path (e.g. `/employees/{id}`). Also double-check that `employments:write` alone is sufficient for termination, or if `employees:manage` should be included.

---

`38-46`: **Review auto_start for incremental employees sync**  
You’ve set `auto_start: false` on the incremental `employees` sync without declaring any metadata inputs. Incremental syncs usually need a cursor or state metadata. Confirm whether you need to define metadata in the input or else allow the sync to auto-start.

---

`48-53`: **Review auto_start for unified-employees sync**  
Similarly, `auto_start: false` is configured for the `unified-employees` sync but no metadata is documented. Ensure you either add the required metadata input or revert to the default auto-start behavior.

---

`66-75`: **GustoCreateEmployee model adheres to schema guidelines**  
Required and optional fields use correct types and the `?` suffix for optional properties. This aligns well with the official schema conventions.

---

`76-81`: **GustoCreateEmployeeResponse model is well-defined**  
The response model includes the expected identifiers and name/email fields, matching the action output.

---

`82-93`: **GustoUpdateEmployee model correctly extends IdEntity**  
It properly inherits `id`, includes a `version` field, and marks all updateable properties as optional.

---

`94-96`: **GustoUpdateEmployeeResponse model extension looks good**  
Extending `GustoCreateEmployeeResponse` DRYs up shared fields and keeps the schema concise.

---

`97-100`: **GustoTerminateEmployee model is defined properly**  
It extends `IdEntity` and correctly uses optional properties for `effectiveDate` and `runTerminationPayroll`.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-09T19:58:35Z
user: login: khaliqgant
body: Looks good! Thanks
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T07:53:47Z

Review comments:
diff_hunk: @@ -1,6 +1,6 @@
 import { vi, expect, it, describe } from 'vitest';
 
-import runAction from '../actions/delete-user.js';
+import runAction from '../actions/terminate-employee.js';
path: integrations/gusto/tests/gusto-demo-delete-user.test.ts
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Correct import but test still refers to delete-user**

The import has been correctly updated to `terminate-employee.js`, aligning with the refactoring from user-focused to employee-focused actions. However, the test description (line 5) and mock configuration (lines 6-10) still refer to "delete-user". 


```diff
- import runAction from '../actions/terminate-employee.js';
+ import runAction from '../actions/terminate-employee.js';

- describe('gusto-demo delete-user tests', () => {
+ describe('gusto-demo terminate-employee tests', () => {
    const nangoMock = new global.vitest.NangoActionMock({
        dirname: __dirname,
-        name: 'delete-user',
+        name: 'terminate-employee',
        Model: 'SuccessResponse'
    });
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
import runAction from '../actions/terminate-employee.js';

describe('gusto-demo terminate-employee tests', () => {
  const nangoMock = new global.vitest.NangoActionMock({
    dirname: __dirname,
    name: 'terminate-employee',
    Model: 'SuccessResponse'
  });

  // …rest of the test…
});
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-09T19:58:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,6 +1,6 @@
 import { vi, expect, it, describe } from 'vitest';
 
-import runAction from '../actions/create-user.js';
+import runAction from '../actions/create-employee.js';
path: integrations/gusto/tests/gusto-demo-create-user.test.ts
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Correct import but test still refers to create-user**

The import has been properly updated to `create-employee.js`, but the test description (line 5) and mock configuration (lines 6-10) still use "create-user" terminology. To maintain consistency with the employee-focused refactoring, these references should be updated.


```diff
- import runAction from '../actions/create-employee.js';
+ import runAction from '../actions/create-employee.js';

- describe('gusto-demo create-user tests', () => {
+ describe('gusto-demo create-employee tests', () => {
    const nangoMock = new global.vitest.NangoActionMock({
        dirname: __dirname,
-        name: 'create-user',
+        name: 'create-employee',
-        Model: 'User'
+        Model: 'GustoCreateEmployeeResponse'
    });
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
import runAction from '../actions/create-employee.js';

describe('gusto-demo create-employee tests', () => {
    const nangoMock = new global.vitest.NangoActionMock({
        dirname: __dirname,
        name: 'create-employee',
        Model: 'GustoCreateEmployeeResponse'
    });
    // ...
});
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-09T19:58:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,6 +1,6 @@
 import { vi, expect, it, describe } from 'vitest';
 
-import runAction from '../actions/delete-user.js';
+import runAction from '../actions/terminate-employee.js';
path: integrations/gusto/tests/gusto-delete-user.test.ts
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Correct import but test still uses delete-user terminology**

The import has been updated to `terminate-employee.js`, but the test description (line 5) and mock configuration (lines 6-10) continue to use "delete-user". For consistency with the employee-focused refactoring, these references should be updated.


```diff
- import runAction from '../actions/terminate-employee.js';
+ import runAction from '../actions/terminate-employee.js';

- describe('gusto delete-user tests', () => {
+ describe('gusto terminate-employee tests', () => {
    const nangoMock = new global.vitest.NangoActionMock({
        dirname: __dirname,
-        name: 'delete-user',
+        name: 'terminate-employee',
        Model: 'SuccessResponse'
    });
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
import runAction from '../actions/terminate-employee.js';

describe('gusto terminate-employee tests', () => {
  const nangoMock = new global.vitest.NangoActionMock({
    dirname: __dirname,
    name: 'terminate-employee',
    Model: 'SuccessResponse'
  });

  // ...rest of your tests
});
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-09T19:58:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,6 +1,6 @@
 import { vi, expect, it, describe } from 'vitest';
 
-import runAction from '../actions/create-user.js';
+import runAction from '../actions/create-employee.js';
path: integrations/gusto/tests/gusto-create-user.test.ts
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Correct import but test still uses create-user terminology**

The import has been updated to `create-employee.js`, but the test description (line 5) and mock configuration (lines 6-10) continue to use "create-user" terminology. For consistency with the employee-focused refactoring, these references should be updated.


```diff
- import runAction from '../actions/create-employee.js';
+ import runAction from '../actions/create-employee.js';

- describe('gusto create-user tests', () => {
+ describe('gusto create-employee tests', () => {
    const nangoMock = new global.vitest.NangoActionMock({
        dirname: __dirname,
-        name: 'create-user',
+        name: 'create-employee',
-        Model: 'User'
+        Model: 'GustoCreateEmployeeResponse'
    });
```

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-09T19:58:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,21 +1,21 @@
 <!-- BEGIN GENERATED CONTENT -->
-# Delete User
+# Terminate Employee
 
 ## General Information
 
-- **Description:** Deletes a user in Gusto.
+- **Description:** Terminates an employee in Gusto.
 - **Version:** 0.0.1
-- **Group:** Users
+- **Group:** Employees
 - **Scopes:** `employments:write`
 - **Endpoint Type:** Action
-- **Code:** [github.com](https://github.com/NangoHQ/integration-templates/tree/main/integrations/gusto/actions/delete-user.ts)
+- **Code:** [github.com](https://github.com/NangoHQ/integration-templates/tree/main/integrations/gusto/actions/terminate-employee.ts)
 
 
 ## Endpoint Reference
 
 ### Request Endpoint
 
-`DELETE /users`
+`DELETE /employees`
path: integrations/gusto/actions/terminate-employee.md
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Endpoint URL doesn't match implementation**

The documented endpoint `DELETE /employees` doesn't match the actual implementation in the code which uses `/v1/employees/${input.id}/terminations`. This discrepancy could confuse API users.

```diff
-`DELETE /employees`
+`DELETE /v1/employees/:id/terminations`
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
`DELETE /v1/employees/:id/terminations`
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-09T19:58:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,58 @@
+<!-- BEGIN GENERATED CONTENT -->
+# Update Employee
+
+## General Information
+
+- **Description:** Updates an employee in Gusto.
+- **Version:** 0.0.1
+- **Group:** Employees
+- **Scopes:** `employees:manage`
+- **Endpoint Type:** Action
+- **Code:** [github.com](https://github.com/NangoHQ/integration-templates/tree/main/integrations/gusto/actions/update-employee.ts)
+
+
+## Endpoint Reference
+
+### Request Endpoint
+
+`PUT /employees`
path: integrations/gusto/actions/update-employee.md
user: login: coderabbitai[bot]
body: _💡 Verification agent_

<details>
<summary>🧩 Analysis chain</summary>

**Verify API endpoint format**

The endpoint is documented as `PUT /employees` but the actual implementation likely uses a path parameter for the employee ID. Please verify that this matches the implementation.

---

🏁 Script executed:

```shell
#!/bin/bash
# Check the update-employee.ts file to confirm the actual endpoint used
cat integrations/gusto/actions/update-employee.ts | grep -A 5 "endpoint:"
```

Length of output: 236

---



</details>

**Align documented endpoint with implementation**

The docs currently list:
```
PUT /employees
```
but the code sends requests to:
```
PUT /v1/employees/${employeeId}
```
Please update the documentation to:
```
PUT /v1/employees/{employeeId}
```
Locations to update:
- integrations/gusto/actions/update-employee.md (around line 18)

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-09T19:58:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -21,44 +21,65 @@
             "required": ["id"],
             "additionalProperties": false
         },
-        "User": {
+        "GustoCreateEmployee": {
             "type": "object",
             "properties": {
-                "id": {
+                "firstName": {
+                    "type": "string"
+                },
+                "lastName": {
                     "type": "string"
                 },
                 "email": {
                     "type": "string"
                 },
-                "firstName": {
+                "middleInitial": {
                     "type": "string"
                 },
-                "lastName": {
+                "preferredFirstName": {
+                    "type": "string"
+                },
+                "dateOfBirth": {
+                    "type": "string"
+                },
+                "ssn": {
                     "type": "string"
+                },
+                "selfOnboarding": {
+                    "type": "boolean"
                 }
             },
-            "required": ["id", "email", "firstName", "lastName"],
+            "required": ["firstName", "lastName", "email", "dateOfBirth"],
             "additionalProperties": false
         },
path: integrations/gusto/.nango/schema.json
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Add missing semantic formats to improve validation accuracy**

`email` and `dateOfBirth` are plain `"type": "string"`.  Clients will benefit from stronger guarantees (e.g. ISO-8601 date, RFC-5322 email).

```diff
@@
-                "email": {
-                    "type": "string"
+                "email": {
+                    "type": "string",
+                    "format": "email"
                 },
@@
-                "dateOfBirth": {
-                    "type": "string"
+                "dateOfBirth": {
+                    "type": "string",
+                    "format": "date"
                 },
```

Adding the `format` keyword costs nothing (draft-07 already supports it) and immediately tightens server-side and editor tooling validation.  



<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
        "GustoCreateEmployee": {
            "type": "object",
            "properties": {
                "firstName": {
                    "type": "string"
                },
                "lastName": {
                    "type": "string"
                },
                "email": {
                    "type": "string",
                    "format": "email"
                },
                "middleInitial": {
                    "type": "string"
                },
                "preferredFirstName": {
                    "type": "string"
                },
                "dateOfBirth": {
                    "type": "string",
                    "format": "date"
                },
                "ssn": {
                    "type": "string"
                },
                "selfOnboarding": {
                    "type": "boolean"
                }
            },
            "required": ["firstName", "lastName", "email", "dateOfBirth"],
            "additionalProperties": false
        },
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-09T19:58:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -11,31 +11,45 @@ export interface IdEntity {
     id: string;
 }
 
-export interface User {
-    id: string;
-    email: string;
+export interface GustoCreateEmployee {
     firstName: string;
     lastName: string;
+    email: string;
+    middleInitial?: string;
+    preferredFirstName?: string;
+    dateOfBirth: string;
+    ssn?: string;
+    selfOnboarding?: boolean;
 }
 
-export interface CreateUser {
+export interface GustoCreateEmployeeResponse {
+    id: string;
+    email: string;
     firstName: string;
     lastName: string;
-    email: string;
 }
 
-export interface GustoCreateUser {
-    firstName: string;
-    lastName: string;
-    email: string;
+export interface GustoUpdateEmployee {
+    id: string;
+    version: string;
+    firstName?: string;
+    lastName?: string;
+    email?: string;
     middleInitial?: string;
     preferredFirstName?: string;
-    dateOfBirth: string;
+    dateOfBirth?: string;
     ssn?: string;
-    selfOnboarding?: boolean;
+    twoPercentShareholder?: boolean;
+}
+
path: integrations/gusto/.nango/schema.ts
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Use a numeric type for `version` in Update DTO**

The interface models `version` as `string`, but Gusto’s optimistic-locking field is numeric.  Surfacing it as `number`:

```diff
-export interface GustoUpdateEmployee {
-    id: string;
-    version: string;
+export interface GustoUpdateEmployee {
+    id: string;
+    version: number;
```

avoids downstream `parseInt()` calls and keeps type-checking honest.  



<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
export interface GustoUpdateEmployee {
    id: string;
    version: number;
    firstName?: string;
    lastName?: string;
    email?: string;
    middleInitial?: string;
    preferredFirstName?: string;
    dateOfBirth?: string;
    ssn?: string;
    twoPercentShareholder?: boolean;
}
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-09T19:58:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -6731,40 +6731,37 @@ integrations:
                 openings: string[]
     gusto:
         actions:
-            create-user:
-                description: Creates a user in Gusto.
-                output: User
+            create-employee:
+                description: Creates an employee in Gusto.
+                output: GustoCreateEmployeeResponse
                 endpoint:
                     method: POST
-                    path: /users
-                    group: Users
-                input: GustoCreateUser
+                    path: /employees
+                    group: Employees
+                input: GustoCreateEmployee
                 scopes:
                     - employees:manage
-            delete-user:
-                description: Deletes a user in Gusto.
+            update-employee:
+                description: Updates an employee in Gusto.
+                output: GustoUpdateEmployeeResponse
+                endpoint:
+                    method: PUT
+                    path: /employees
+                    group: Employees
+                input: GustoUpdateEmployee
+                scopes:
+                    - employees:manage
+            terminate-employee:
+                description: Terminates an employee in Gusto.
                 endpoint:
                     method: DELETE
-                    path: /users
-                    group: Users
+                    path: /employees
+                    group: Employees
                 output: SuccessResponse
-                input: GustoDeleteUser
+                input: GustoTerminateEmployee
                 scopes:
                     - employments:write
         syncs:
-            users:
-                runs: every day
-                description: |
-                    Fetches a list of users from Gusto.
-                output: User
-                track_deletes: true
-                sync_type: full
-                endpoint:
-                    method: GET
-                    path: /users
-                    group: Users
-                scopes:
-                    - employees:read
             employees:
                 runs: every 5m
                 description: Fetches all employees from Gusto
path: flows.yaml
user: login: coderabbitai[bot]
body: _💡 Verification agent_

<details>
<summary>❓ Verification inconclusive</summary>

**Fix update/delete endpoint paths and define sync action.**

The `update-employee` and `terminate-employee` endpoints currently point to `/employees` for PUT/DELETE. Gusto’s API requires a resource ID in the path (e.g. `/employees/{{ input.id }}`) so that the correct employee is targeted. Additionally, the `employees` sync block lacks an `action` property (for example `list-employees`), which is needed to drive the sync. Please verify the API spec and update these flows accordingly.

---



</details>

**Fix update/delete endpoint paths and add sync action**

The `update-employee` and `terminate-employee` endpoints must include the employee ID in the path (e.g. `/employees/{{ input.id }}`) so the correct resource is targeted. Additionally, the `employees` sync block requires an `action` property to drive the sync.

Please update in `flows.yaml`:

- update-employee.endpoint.path: change from `/employees` to `/employees/{{ input.id }}`
- terminate-employee.endpoint.path: change from `/employees` to `/employees/{{ input.id }}`
- syncs.employees: add `action: list-employees`

```diff
... flows.yaml ...
 update-employee:
     endpoint:
         method: PUT
-        path: /employees
+        path: /employees/{{ input.id }}

 terminate-employee:
     endpoint:
         method: DELETE
-        path: /employees
+        path: /employees/{{ input.id }}

 syncs:
     employees:
         runs: every 5m
         description: Fetches all employees from Gusto
+        action: list-employees
```



<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
            update-employee:
                description: Updates an employee in Gusto.
                output: GustoUpdateEmployeeResponse
                endpoint:
                    method: PUT
                    path: /employees/{{ input.id }}
                    group: Employees
                input: GustoUpdateEmployee
                scopes:
                    - employees:manage
            terminate-employee:
                description: Terminates an employee in Gusto.
                endpoint:
                    method: DELETE
                    path: /employees/{{ input.id }}
                    group: Employees
                output: SuccessResponse
                input: GustoTerminateEmployee
                scopes:
                    - employments:write
        syncs:
            employees:
                runs: every 5m
                description: Fetches all employees from Gusto
                action: list-employees
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-09T19:58:34Z
author_association: CONTRIBUTOR

PR comments:
user: login: linear[bot]
created_at: 2025-05-09T16:10:10Z
body: <p><a href="https://linear.app/nango/issue/NAN-3063/gusto-syncs-and-actions-clean-up">NAN-3063 Gusto syncs and actions + clean up</a></p>
author_association: NONE
user: login: coderabbitai[bot]
created_at: 2025-05-09T16:10:13Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough

This change refactors the Gusto and Gusto-demo integrations to replace all "user" terminology, actions, and models with "employee"-centric equivalents. Actions for creating, updating, and terminating users are now create-employee, update-employee, and terminate-employee, using `/employees` endpoints and updated OAuth scopes. All related models and schemas have been renamed and expanded to reflect employee-specific fields and requirements. The previous user sync and documentation were removed, leaving only employee-related syncs. Test imports and documentation were updated to match the new naming, and detailed schemas for employee data, creation, update, and termination were introduced.

## Possibly related PRs

- `NangoHQ/integration-templates#303`: Fixes import paths and adds explicit typing to the employee sync introduced in this refactor, directly related to the new employee sync implementation.
- `NangoHQ/integration-templates#301`: Adds unified HRIS employee models and syncs across multiple integrations including Gusto, aligning with the employee model changes in this refactor.

## Suggested labels

`Automation`

<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: .coderabbit.yaml**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 4d44279ae25cd038b2cc3173735dd330b1e72522 and b3452a4b47c7a42014622c2499f200a06d3aec0a.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `flows.yaml` (6 hunks)

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (1)</summary>

* flows.yaml

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (4)</summary>

* GitHub Check: tests (ubuntu-latest, 20.x)
* GitHub Check: tests (ubuntu-latest, 18.x)
* GitHub Check: lint-code
* GitHub Check: flow-compilation

</details>

</details>
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=NangoHQ/integration-templates&utm_content=322):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR