-
Notifications
You must be signed in to change notification settings - Fork 10.2k
feat: refactor Deel app to OAuth integration with automatic time-off creation #22442
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: refactor Deel app to OAuth integration with automatic time-off creation #22442
Conversation
…creation - Convert Deel app from redirect-only to full OAuth integration - Add OAuth authorization flow with Deel API - Implement DeelService for time-off request creation - Integrate with OOO system to automatically create Deel time-off requests - Follow existing Cal.com OAuth patterns (similar to HubSpot integration) - Add proper credential storage and token management - Update app metadata and configuration for OAuth template Co-Authored-By: anik@cal.com <anik@cal.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 2 Skipped Deployments
|
✅ No security or compliance issues detected. Reviewed everything up to e58c2c6. Security Overview
Detected Code ChangesThe diff is too large to display a summary of code changes. Reply to this PR with |
E2E results are ready! |
Graphite Automations"Add consumer team as reviewer" took an action on this PR • (07/12/25)1 reviewer was added to this PR based on Keith Williams's automation. |
@cubic-dev-ai pls review |
@anikdhabal I've started the AI code review. It'll take a few minutes to complete. |
import type { DeelToken } from "../api/callback"; | ||
|
||
export interface DeelTimeOffRequest { | ||
employee_id: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is wrong. As per thier docs we need to pass recipient_profile_id (The hris profile id of the recipient) instead of it. So pls fix it
…and time_off_type_id - Replace employee_id with recipient_profile_id in DeelTimeOffRequest interface - Replace time_off_type with time_off_type_id in DeelTimeOffRequest interface - Add new interfaces for DeelTimeOffType, DeelPolicy, and DeelPoliciesResponse - Rename getEmployeeId to getRecipientProfileId method - Add getTimeOffTypeId method to fetch time-off types from List Policies endpoint - Update OOO handler to use new method names and correct API field structure - Implement logic to select appropriate time-off type (prioritizing vacation/PTO) Co-Authored-By: anik@cal.com <anik@cal.com>
…pient_profile_id and policies array from List Policies response Co-Authored-By: anik@cal.com <anik@cal.com>
- Add deelTimeOffId field to OutOfOfficeEntry schema for storing Deel time-off IDs - Implement updateTimeOff and deleteTimeOff methods in DeelService - Integrate update operations in outOfOfficeCreateOrUpdate handler - Integrate delete operations in outOfOfficeEntryDelete handler - Support complete lifecycle: create → update → delete for Deel time-off requests Co-Authored-By: anik@cal.com <anik@cal.com>
Co-Authored-By: anik@cal.com <anik@cal.com>
- Create HrmsService interface similar to CrmService for HRMS operations - Implement HrmsManager class following CrmManager pattern for service instantiation - Add getHrms utility function for mapping credential types to HRMS services - Generate HrmsServiceMap for auto-mapping HRMS apps to their services - Refactor Deel integration to implement HrmsService interface instead of direct imports - Update OOO handlers to use HrmsManager instead of direct Deel service imports - Add HRMS service generation to app-store-cli build process - Update Deel app config to include 'hrms' category - Maintain full CRUD operations (create, update, delete) for time-off requests - Architecture supports multiple HRMS providers for future extensibility Co-Authored-By: anik@cal.com <anik@cal.com>
Co-Authored-By: anik@cal.com <anik@cal.com>
- Make reason field non-unique and externalId field unique in OutOfOfficeReason schema - Add externalId to HRMS mapped response in outOfOfficeReasons.handler.ts - Update CreateOrEditOOOModal to use policy.name/policy.id as label/value when externalId is present - Modify createOOO/updateOOO to use externalId as time_off_type_id instead of fetching from getTimeOffId - Add proper type safety for union types in modal dropdown - Update HrmsManager and HrmsService interfaces to support externalId parameter - Ensure backward compatibility for regular OOO without HRMS integration Co-Authored-By: anik@cal.com <anik@cal.com>
type: "deel_other", | ||
title: "Deel Time Off", | ||
variant: "other", | ||
categories: ["other"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
categories: ["other"], | |
categories: ["other", "hrms"], |
await createOAuthAppCredential({ appId: metadata.slug, type: metadata.type }, deelToken, req); | ||
|
||
res.redirect( | ||
getSafeRedirectUrl(state?.returnTo) ?? getInstalledAppPath({ variant: "other", slug: "deel" }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getSafeRedirectUrl(state?.returnTo) ?? getInstalledAppPath({ variant: "other", slug: "deel" }) | |
getSafeRedirectUrl(state?.returnTo) ?? getInstalledAppPath({ variant: "hrms", slug: "deel" }) |
"isTemplate": false, | ||
"__createdUsingCli": true, | ||
"__template": "link-as-an-app", | ||
"__template": "oauth", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"__template": "oauth", | |
"__template": "link-as-an-app", |
use cli to change this
} | ||
} | ||
} catch (error) { | ||
console.error("Failed to create/update HRMS time-off request:", error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use the logger in @lib/logger for loggin failures for debugging in prod
…or credentialId_externalId Co-Authored-By: anik@cal.com <anik@cal.com>
…tialsByUserIdAndCategory method - Rename findHrmsCredentialsByUserId to findCredentialsByUserIdAndCategory for reusability - Add category parameter to support future CRM, calendar, and other app integrations - Update all OOO handlers to use the new centralized method - Eliminate ~30+ lines of repetitive credential fetching code - Maintain existing functionality while improving maintainability Co-Authored-By: anik@cal.com <anik@cal.com>
- Add webhook endpoint with signature verification using x-deel-signature header - Handle time-off.created events with status APPROVED only - Fetch user details from Deel API using requester.id and match by email - Create OOO entries with proper policy mapping using externalId - Add webhook_signing_key to Deel app configuration schema - Export webhook endpoint from Deel API index - Fix HRMS service import to use named export pattern Co-Authored-By: anik@cal.com <anik@cal.com>
Co-Authored-By: anik@cal.com <anik@cal.com>
… pattern - Add createOOOEntry and upsertOOOReason methods to PrismaOOORepository - Add findByEmailCaseInsensitive method to UserRepository - Add findManyByCategoryAndAppSlug method to CredentialRepository - Refactor webhook handlers to use repository methods instead of direct Prisma calls Co-Authored-By: anik@cal.com <anik@cal.com>
… DeelHrmsService from imported module Co-Authored-By: anik@cal.com <anik@cal.com>
Closing due to inactivity for more than 7 days. Configure here. |
This PR is being marked as stale due to inactivity. |
Schema Refactoring for OutOfOfficeReason with Dynamic HRMS Integration
Summary
This PR implements schema refactoring for the
OutOfOfficeReason
model to support dynamic HRMS integration, specifically allowing OOO reasons to be fetched from external HRMS providers like Deel. The changes include:reason
field non-unique andexternalId
field unique in OutOfOfficeReason modeloutOfOfficeReasons.handler.ts
to fetch and return HRMS policies when credentials are availableCreateOrEditOutOfOfficeModal
to handle mixed ID types (numeric for static reasons, string for HRMS reasons)createOOO
/updateOOO
handlers to useexternalId
directly astime_off_type_id
instead of fetching fromgetTimeOffId
The implementation maintains backward compatibility - existing OOO functionality continues to work unchanged, while HRMS integration is activated when credentials are present.
Review & Testing Checklist for Human
Recommended Test Plan:
Diagram
Notes
20250715045153_make_reason_non_unique_and_external_id_unique