Skip to content
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

refactor: integrations handler #16946

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

Ryukemeister
Copy link
Contributor

@Ryukemeister Ryukemeister commented Oct 4, 2024

What does this PR do?

  • This PR aims to refactor the integrations handler which returns data for all kinds of integrations and app data. There's no major change in logic of the code, just abstraction of a lot of logic into standalone functions.

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have added a Docs issue here if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

This can be tested in the webapp anywhere we have something related to integrations. The best and easiest I found is the app store.

@keithwillcode keithwillcode added core area: core, team members only platform Anything related to our platform plan labels Oct 4, 2024
Copy link

vercel bot commented Oct 4, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
cal ⬜️ Ignored (Inspect) Visit Preview Oct 5, 2024 0:21am
calcom-web-canary ⬜️ Ignored (Inspect) Visit Preview Oct 5, 2024 0:21am

@@ -104,6 +104,16 @@ function getApps(credentials: CredentialDataWithTeamName[], filterOnCredentials?
return apps;
}

export function getAppsBySlug(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to get a specific app instead of all, can be useful for v2 api.

import type { CredentialDataWithTeamName } from "@calcom/app-store/utils";
import type { PaymentApp } from "@calcom/types/PaymentService";

const checkAppSetupStatus = async (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Helper function, abstracted the logic from the integrations handler.


import type { Credentials } from "./getTeamAppCredentials";

const constructUserTeams = async (credentials: Credentials, appSlug: string, userTeams: TeamQuery[]) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Helper function, abstracted the logic from the integrations handler.


import type { EnabledApp } from "./getEnabledAppsFromCredentials";

const getAppDependencyData = (enabledApps: EnabledApp[], dependencies?: string[] | undefined) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Helper function, abstracted the logic from the integrations handler.

@@ -42,6 +45,10 @@ const getEnabledAppsFromCredentials = async (
if (teamIds.length) filterOnIds.credentials.some.OR.push({ teamId: { in: teamIds } });
}

if (!!filterOnAppSlug) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gets a specific app based on slug instead of all.

invalid: boolean | null;
}[];

const getTeamAppCredentials = (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Helper function, abstracted the logic from the integrations handler.

import getUserTeamsQuery from "@calcom/lib/apps/getUserTeamsQuery";
import type { TeamQuery } from "@calcom/trpc/server/routers/loggedInViewer/integrations.handler";

const getUserAvailableTeams = async (userId: number, teamId?: number | null) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Helper function, abstracted the logic from the integrations handler.

import prisma from "@calcom/prisma";
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";

const getUserTeamsQuery = async (userId: number) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another helper function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels better suited to be in a repository

let credentials = await getUsersCredentials(user);
let userTeams: TeamQuery[] = [];

if (includeTeamInstalledApps || teamId) {
const teamsQuery = await prisma.team.findMany({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been abstracted to getUserTeamsQuery function.

});
// If a team is a part of an org then include those apps
// Don't want to iterate over these parent teams
const filteredTeams: TeamQuery[] = [];
Copy link
Contributor Author

@Ryukemeister Ryukemeister Oct 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been abstracted to getUserAvailableTeams function.


userTeams = [...teamsQuery, ...parentTeams];

const teamAppCredentials: CredentialPayload[] = userTeams.flatMap((teamApp) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been abstracted to getTeamAppCredentials function.

@@ -144,56 +69,21 @@ export const integrationsHandler = async ({ ctx, input }: IntegrationsOptions) =
const invalidCredentialIds = credentials
.filter((c) => c.appId === app.slug && c.invalid)
.map((c) => c.id);
const teams = await Promise.all(
Copy link
Contributor Author

@Ryukemeister Ryukemeister Oct 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been abstracted to constructUserTeams function.

// type infer as CredentialOwner
const credentialOwner: CredentialOwner = {
name: user.name,
avatar: user.avatar,
};

// We need to know if app is payment type
// undefined it means that app don't require app/setup/page
let isSetupAlready = undefined;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been abstracted to checkAppSetupStatus function.

}
}

let dependencyData: TDependencyData = [];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been abstracted to getAppDependencyData function.

@Ryukemeister Ryukemeister marked this pull request as ready for review October 5, 2024 12:21
@graphite-app graphite-app bot requested review from a team October 5, 2024 12:21
@dosubot dosubot bot added the 💻 refactor label Oct 5, 2024
@Ryukemeister Ryukemeister requested review from hariombalhara, zomars and joeauyeung and removed request for a team October 5, 2024 12:22
Copy link

graphite-app bot commented Oct 5, 2024

Graphite Automations

"Add platform team as reviewer" took an action on this PR • (10/05/24)

1 reviewer was added to this PR based on Keith Williams's automation.

"Add foundation team as reviewer" took an action on this PR • (10/05/24)

1 reviewer was added to this PR based on Keith Williams's automation.

@@ -39,10 +36,6 @@ type TeamQuery = Prisma.TeamGetPayload<{
};
}>;

// type TeamQueryWithParent = TeamQuery & {
Copy link
Contributor Author

@Ryukemeister Ryukemeister Oct 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joeauyeung removed this code which was commented but I don't if this is needed still or left there by mistake, should I bring it back?

@@ -205,6 +95,8 @@ export const integrationsHandler = async ({ ctx, input }: IntegrationsOptions) =
isSetupAlready,
...(app.dependencies && { dependencyData }),
};

return appData;
})
);

Copy link
Contributor Author

@Ryukemeister Ryukemeister Oct 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was thinking of shifting all the code below into a function of its own, but don't think it'll be really helpful since the logic is fairly simple to understand( just an if conditional ) and there's a lot of variables from input. What do you guys thinkabout this, should we split the code below into its own separate function?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, there's too many variables and if statements involved here not to.


const getTeamAppCredentials = (
userTeams: TeamQuery[],
userCredentialIds: Credentials,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about this? Maybe merge outside of this function to keep this function dumber?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core area: core, team members only high-risk Requires approval by Foundation team platform Anything related to our platform plan 💻 refactor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants