- Want to loop in team mates?{" "}
+ Want to loop in organization mates?{" "}
Invite them.
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(account)/notifications/components/NotificationSwitch.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(account)/notifications/components/NotificationSwitch.tsx
index 027a93595c..e97f70a18c 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(account)/notifications/components/NotificationSwitch.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(account)/notifications/components/NotificationSwitch.tsx
@@ -9,15 +9,15 @@ import { Switch } from "@formbricks/ui/Switch";
import { updateNotificationSettingsAction } from "../actions";
interface NotificationSwitchProps {
- surveyOrProductOrTeamId: string;
+ surveyOrProductOrOrganizationId: string;
notificationSettings: TUserNotificationSettings;
- notificationType: "alert" | "weeklySummary" | "unsubscribedTeamIds";
+ notificationType: "alert" | "weeklySummary" | "unsubscribedOrganizationIds";
autoDisableNotificationType?: string;
autoDisableNotificationElementId?: string;
}
export const NotificationSwitch = ({
- surveyOrProductOrTeamId,
+ surveyOrProductOrOrganizationId,
notificationSettings,
notificationType,
autoDisableNotificationType,
@@ -26,26 +26,29 @@ export const NotificationSwitch = ({
const [isLoading, setIsLoading] = useState(false);
const isChecked =
- notificationType === "unsubscribedTeamIds"
- ? !notificationSettings.unsubscribedTeamIds?.includes(surveyOrProductOrTeamId)
- : notificationSettings[notificationType][surveyOrProductOrTeamId] === true;
+ notificationType === "unsubscribedOrganizationIds"
+ ? !notificationSettings.unsubscribedOrganizationIds?.includes(surveyOrProductOrOrganizationId)
+ : notificationSettings[notificationType][surveyOrProductOrOrganizationId] === true;
const handleSwitchChange = async () => {
setIsLoading(true);
let updatedNotificationSettings = { ...notificationSettings };
- if (notificationType === "unsubscribedTeamIds") {
- const unsubscribedTeamIds = updatedNotificationSettings.unsubscribedTeamIds ?? [];
- if (unsubscribedTeamIds.includes(surveyOrProductOrTeamId)) {
- updatedNotificationSettings.unsubscribedTeamIds = unsubscribedTeamIds.filter(
- (id) => id !== surveyOrProductOrTeamId
+ if (notificationType === "unsubscribedOrganizationIds") {
+ const unsubscribedOrganizationIds = updatedNotificationSettings.unsubscribedOrganizationIds ?? [];
+ if (unsubscribedOrganizationIds.includes(surveyOrProductOrOrganizationId)) {
+ updatedNotificationSettings.unsubscribedOrganizationIds = unsubscribedOrganizationIds.filter(
+ (id) => id !== surveyOrProductOrOrganizationId
);
} else {
- updatedNotificationSettings.unsubscribedTeamIds = [...unsubscribedTeamIds, surveyOrProductOrTeamId];
+ updatedNotificationSettings.unsubscribedOrganizationIds = [
+ ...unsubscribedOrganizationIds,
+ surveyOrProductOrOrganizationId,
+ ];
}
} else {
- updatedNotificationSettings[notificationType][surveyOrProductOrTeamId] =
- !updatedNotificationSettings[notificationType][surveyOrProductOrTeamId];
+ updatedNotificationSettings[notificationType][surveyOrProductOrOrganizationId] =
+ !updatedNotificationSettings[notificationType][surveyOrProductOrOrganizationId];
}
await updateNotificationSettingsAction(updatedNotificationSettings);
@@ -55,12 +58,12 @@ export const NotificationSwitch = ({
useEffect(() => {
if (
autoDisableNotificationType &&
- autoDisableNotificationElementId === surveyOrProductOrTeamId &&
+ autoDisableNotificationElementId === surveyOrProductOrOrganizationId &&
isChecked
) {
switch (notificationType) {
case "alert":
- if (notificationSettings[notificationType][surveyOrProductOrTeamId] === true) {
+ if (notificationSettings[notificationType][surveyOrProductOrOrganizationId] === true) {
handleSwitchChange();
toast.success("You will not receive any more emails for responses on this survey!", {
id: "notification-switch",
@@ -68,10 +71,10 @@ export const NotificationSwitch = ({
}
break;
- case "unsubscribedTeamIds":
- if (!notificationSettings.unsubscribedTeamIds?.includes(surveyOrProductOrTeamId)) {
+ case "unsubscribedOrganizationIds":
+ if (!notificationSettings.unsubscribedOrganizationIds?.includes(surveyOrProductOrOrganizationId)) {
handleSwitchChange();
- toast.success("You will not be auto-subscribed to this team's surveys anymore!", {
+ toast.success("You will not be auto-subscribed to this organization's surveys anymore!", {
id: "notification-switch",
});
}
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(account)/notifications/page.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(account)/notifications/page.tsx
index 9423ae1c15..22297e0f48 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(account)/notifications/page.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(account)/notifications/page.tsx
@@ -21,10 +21,10 @@ const setCompleteNotificationSettings = (
const newNotificationSettings = {
alert: {},
weeklySummary: {},
- unsubscribedTeamIds: notificationSettings.unsubscribedTeamIds || [],
+ unsubscribedOrganizationIds: notificationSettings.unsubscribedOrganizationIds || [],
};
for (const membership of memberships) {
- for (const product of membership.team.products) {
+ for (const product of membership.organization.products) {
// set default values for weekly summary
newNotificationSettings.weeklySummary[product.id] =
(notificationSettings.weeklySummary && notificationSettings.weeklySummary[product.id]) || false;
@@ -48,7 +48,7 @@ const getMemberships = async (userId: string): Promise => {
userId,
},
select: {
- team: {
+ organization: {
select: {
id: true,
name: true,
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(account)/notifications/types.ts b/apps/web/app/(app)/environments/[environmentId]/settings/(account)/notifications/types.ts
index 57f3d30b0e..ca3f2848a7 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(account)/notifications/types.ts
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(account)/notifications/types.ts
@@ -1,7 +1,7 @@
import { TUserNotificationSettings } from "@formbricks/types/user";
export interface Membership {
- team: {
+ organization: {
id: string;
name: string;
products: {
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(account)/profile/components/DeleteAccount.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(account)/profile/components/DeleteAccount.tsx
index 4002fff3e0..beba3685e4 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(account)/profile/components/DeleteAccount.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(account)/profile/components/DeleteAccount.tsx
@@ -72,12 +72,12 @@ const DeleteAccountModal = ({ setOpen, open, session, IS_FORMBRICKS_CLOUD }: Del
Permanent removal of all of your personal information and data.
- If you are the owner of a team with other admins, the ownership of that team will be transferred
- to another admin.
+ If you are the owner of an organization with other admins, the ownership of that organization will
+ be transferred to another admin.
- If you are the only member of a team or there is no other admin present, the team will be
- irreversibly deleted along with all associated data.
+ If you are the only member of an organization or there is no other admin present, the organization
+ will be irreversibly deleted along with all associated data.
This action cannot be undone. If it's gone, it's gone.
) : (
@@ -283,13 +289,13 @@ export const PricingTable = ({
featureName={ProductFeatureKeys[ProductFeatureKeys.inAppSurvey]}
monthlyPrice={0}
actionText={"Starting at"}
- team={team}
+ organization={organization}
metric="responses"
sliderValue={responseCount}
sliderLimit={350}
freeTierLimit={appSurveyFreeResponses}
paidFeatures={coreAndWebAppSurveyFeatures.filter((feature) => {
- if (team.billing.features.inAppSurvey.unlimited) {
+ if (organization.billing.features.inAppSurvey.unlimited) {
return feature.unlimited !== false;
} else {
return feature.unlimited !== true;
@@ -307,7 +313,7 @@ export const PricingTable = ({
featureName={ProductFeatureKeys[ProductFeatureKeys.linkSurvey]}
monthlyPrice={30}
actionText={""}
- team={team}
+ organization={organization}
paidFeatures={linkSurveysFeatures}
loading={upgradingPlan}
onUpgrade={() => upgradePlan([StripePriceLookupKeys.linkSurvey])}
@@ -320,13 +326,13 @@ export const PricingTable = ({
featureName={ProductFeatureKeys[ProductFeatureKeys.userTargeting]}
monthlyPrice={0}
actionText={"Starting at"}
- team={team}
+ organization={organization}
metric="people"
sliderValue={peopleCount}
sliderLimit={3500}
freeTierLimit={userTargetingFreeMtu}
paidFeatures={userTargetingFeatures.filter((feature) => {
- if (team.billing.features.userTargeting.unlimited) {
+ if (organization.billing.features.userTargeting.unlimited) {
return feature.unlimited !== false;
} else {
return feature.unlimited !== true;
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/billing/layout.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/billing/layout.tsx
similarity index 67%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/billing/layout.tsx
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/billing/layout.tsx
index 74386fbb1d..4ec2e9ac3e 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/billing/layout.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/billing/layout.tsx
@@ -4,9 +4,9 @@ import { notFound } from "next/navigation";
import { authOptions } from "@formbricks/lib/authOptions";
import { IS_FORMBRICKS_CLOUD } from "@formbricks/lib/constants";
-import { getMembershipByUserIdTeamId } from "@formbricks/lib/membership/service";
+import { getMembershipByUserIdOrganizationId } from "@formbricks/lib/membership/service";
import { getAccessFlags } from "@formbricks/lib/membership/utils";
-import { getTeamByEnvironmentId } from "@formbricks/lib/team/service";
+import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
import { ErrorComponent } from "@formbricks/ui/ErrorComponent";
export const metadata: Metadata = {
@@ -19,16 +19,16 @@ const BillingLayout = async ({ children, params }) => {
}
const session = await getServerSession(authOptions);
- const team = await getTeamByEnvironmentId(params.environmentId);
+ const organization = await getOrganizationByEnvironmentId(params.environmentId);
if (!session) {
throw new Error("Unauthorized");
}
- if (!team) {
- throw new Error("Team not found");
+ if (!organization) {
+ throw new Error("Organization not found");
}
- const currentUserMembership = await getMembershipByUserIdTeamId(session?.user.id, team.id);
+ const currentUserMembership = await getMembershipByUserIdOrganizationId(session?.user.id, organization.id);
const { isAdmin, isOwner } = getAccessFlags(currentUserMembership?.role);
const isPricingDisabled = !isOwner && !isAdmin;
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/billing/loading.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/billing/loading.tsx
similarity index 100%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/billing/loading.tsx
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/billing/loading.tsx
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/billing/page.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/billing/page.tsx
similarity index 57%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/billing/page.tsx
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/billing/page.tsx
index f95e51f04d..8baed6ba3e 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/billing/page.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/billing/page.tsx
@@ -1,4 +1,4 @@
-import { TeamSettingsNavbar } from "@/app/(app)/environments/[environmentId]/settings/(team)/components/TeamSettingsNavbar";
+import { OrganizationSettingsNavbar } from "@/app/(app)/environments/[environmentId]/settings/(organization)/components/OrganizationSettingsNavbar";
import { getServerSession } from "next-auth";
import { authOptions } from "@formbricks/lib/authOptions";
@@ -7,21 +7,21 @@ import {
PRICING_APPSURVEYS_FREE_RESPONSES,
PRICING_USERTARGETING_FREE_MTU,
} from "@formbricks/lib/constants";
-import { getMembershipByUserIdTeamId } from "@formbricks/lib/membership/service";
+import { getMembershipByUserIdOrganizationId } from "@formbricks/lib/membership/service";
import {
- getMonthlyActiveTeamPeopleCount,
- getMonthlyTeamResponseCount,
- getTeamByEnvironmentId,
-} from "@formbricks/lib/team/service";
+ getMonthlyActiveOrganizationPeopleCount,
+ getMonthlyOrganizationResponseCount,
+ getOrganizationByEnvironmentId,
+} from "@formbricks/lib/organization/service";
import { PageContentWrapper } from "@formbricks/ui/PageContentWrapper";
import { PageHeader } from "@formbricks/ui/PageHeader";
import { PricingTable } from "./components/PricingTable";
const Page = async ({ params }) => {
- const team = await getTeamByEnvironmentId(params.environmentId);
- if (!team) {
- throw new Error("Team not found");
+ const organization = await getOrganizationByEnvironmentId(params.environmentId);
+ if (!organization) {
+ throw new Error("Organization not found");
}
const session = await getServerSession(authOptions);
@@ -30,16 +30,16 @@ const Page = async ({ params }) => {
}
const [peopleCount, responseCount] = await Promise.all([
- getMonthlyActiveTeamPeopleCount(team.id),
- getMonthlyTeamResponseCount(team.id),
+ getMonthlyActiveOrganizationPeopleCount(organization.id),
+ getMonthlyOrganizationResponseCount(organization.id),
]);
- const currentUserMembership = await getMembershipByUserIdTeamId(session?.user.id, team.id);
+ const currentUserMembership = await getMembershipByUserIdOrganizationId(session?.user.id, organization.id);
return (
-
-
+ {
/>
{
- const team = await getTeamByEnvironmentId(params.environmentId);
- if (!team) {
- throw new Error("Team not found");
+ const organization = await getOrganizationByEnvironmentId(params.environmentId);
+ if (!organization) {
+ throw new Error("Organization not found");
}
- const { status, newPlan, url } = await upgradePlanAction(team.id, params.environmentId, [
+ const { status, newPlan, url } = await upgradePlanAction(organization.id, params.environmentId, [
StripePriceLookupKeys.inAppSurveyUnlimitedPlan90,
StripePriceLookupKeys.linkSurveyUnlimitedPlan19,
StripePriceLookupKeys.userTargetingUnlimitedPlan90,
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/billing/unlimited99/page.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/billing/unlimited99/page.tsx
similarity index 66%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/billing/unlimited99/page.tsx
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/billing/unlimited99/page.tsx
index a07ea3dd26..0d2cf4cd1e 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/billing/unlimited99/page.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/billing/unlimited99/page.tsx
@@ -1,17 +1,17 @@
import { redirect } from "next/navigation";
import { StripePriceLookupKeys } from "@formbricks/ee/billing/lib/constants";
-import { getTeamByEnvironmentId } from "@formbricks/lib/team/service";
+import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
import { upgradePlanAction } from "../actions";
const Page = async ({ params }) => {
- const team = await getTeamByEnvironmentId(params.environmentId);
- if (!team) {
- throw new Error("Team not found");
+ const organization = await getOrganizationByEnvironmentId(params.environmentId);
+ if (!organization) {
+ throw new Error("Organization not found");
}
- const { status, newPlan, url } = await upgradePlanAction(team.id, params.environmentId, [
+ const { status, newPlan, url } = await upgradePlanAction(organization.id, params.environmentId, [
StripePriceLookupKeys.inAppSurveyUnlimitedPlan33,
StripePriceLookupKeys.linkSurveyUnlimitedPlan33,
StripePriceLookupKeys.userTargetingUnlimitedPlan33,
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/components/TeamSettingsNavbar.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/components/OrganizationSettingsNavbar.tsx
similarity index 97%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/components/TeamSettingsNavbar.tsx
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/components/OrganizationSettingsNavbar.tsx
index 07ff1131f4..d9eb753fd9 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/components/TeamSettingsNavbar.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/components/OrganizationSettingsNavbar.tsx
@@ -7,7 +7,7 @@ import { getAccessFlags } from "@formbricks/lib/membership/utils";
import { TMembershipRole } from "@formbricks/types/memberships";
import { SecondaryNavigation } from "@formbricks/ui/SecondaryNavigation";
-export const TeamSettingsNavbar = ({
+export const OrganizationSettingsNavbar = ({
environmentId,
isFormbricksCloud,
membershipRole,
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/enterprise/loading.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/enterprise/loading.tsx
similarity index 100%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/enterprise/loading.tsx
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/enterprise/loading.tsx
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/enterprise/page.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/enterprise/page.tsx
similarity index 89%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/enterprise/page.tsx
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/enterprise/page.tsx
index 0b776f45e5..f422e99b12 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/enterprise/page.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/enterprise/page.tsx
@@ -1,4 +1,4 @@
-import { TeamSettingsNavbar } from "@/app/(app)/environments/[environmentId]/settings/(team)/components/TeamSettingsNavbar";
+import { OrganizationSettingsNavbar } from "@/app/(app)/environments/[environmentId]/settings/(organization)/components/OrganizationSettingsNavbar";
import { CheckIcon } from "lucide-react";
import { getServerSession } from "next-auth";
import { notFound } from "next/navigation";
@@ -6,9 +6,9 @@ import { notFound } from "next/navigation";
import { getIsEnterpriseEdition } from "@formbricks/ee/lib/service";
import { authOptions } from "@formbricks/lib/authOptions";
import { IS_FORMBRICKS_CLOUD } from "@formbricks/lib/constants";
-import { getMembershipByUserIdTeamId } from "@formbricks/lib/membership/service";
+import { getMembershipByUserIdOrganizationId } from "@formbricks/lib/membership/service";
import { getAccessFlags } from "@formbricks/lib/membership/utils";
-import { getTeamByEnvironmentId } from "@formbricks/lib/team/service";
+import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
import { Button } from "@formbricks/ui/Button";
import { PageContentWrapper } from "@formbricks/ui/PageContentWrapper";
import { PageHeader } from "@formbricks/ui/PageHeader";
@@ -20,17 +20,17 @@ const Page = async ({ params }) => {
const session = await getServerSession(authOptions);
- const team = await getTeamByEnvironmentId(params.environmentId);
+ const organization = await getOrganizationByEnvironmentId(params.environmentId);
if (!session) {
throw new Error("Unauthorized");
}
- if (!team) {
- throw new Error("Team not found");
+ if (!organization) {
+ throw new Error("Organization not found");
}
- const currentUserMembership = await getMembershipByUserIdTeamId(session?.user.id, team.id);
+ const currentUserMembership = await getMembershipByUserIdOrganizationId(session?.user.id, organization.id);
const { isAdmin, isOwner } = getAccessFlags(currentUserMembership?.role);
const isPricingDisabled = !isOwner && !isAdmin;
@@ -47,7 +47,7 @@ const Page = async ({ params }) => {
onRequest: false,
},
{
- title: "Team Access Roles (Admin, Editor, Developer, etc.)",
+ title: "Organization Roles (Admin, Editor, Developer, etc.)",
comingSoon: false,
onRequest: false,
},
@@ -85,8 +85,8 @@ const Page = async ({ params }) => {
return (
-
-
+ {
- const [team, product, session] = await Promise.all([
- getTeamByEnvironmentId(params.environmentId),
+ const [organization, product, session] = await Promise.all([
+ getOrganizationByEnvironmentId(params.environmentId),
getProductByEnvironmentId(params.environmentId),
getServerSession(authOptions),
]);
- if (!team) {
- throw new Error("Team not found");
+ if (!organization) {
+ throw new Error("Organization not found");
}
if (!product) {
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/actions.ts b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/actions.ts
similarity index 66%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/actions.ts
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/actions.ts
index 477a5905e9..39dccc1972 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/actions.ts
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/actions.ts
@@ -3,43 +3,43 @@
import { getServerSession } from "next-auth";
import { sendInviteMemberEmail } from "@formbricks/email";
-import { hasTeamAuthority } from "@formbricks/lib/auth";
+import { hasOrganizationAuthority } from "@formbricks/lib/auth";
import { authOptions } from "@formbricks/lib/authOptions";
import { INVITE_DISABLED } from "@formbricks/lib/constants";
import { deleteInvite, getInvite, inviteUser, resendInvite } from "@formbricks/lib/invite/service";
import { createInviteToken } from "@formbricks/lib/jwt";
import {
deleteMembership,
- getMembershipByUserIdTeamId,
+ getMembershipByUserIdOrganizationId,
getMembershipsByUserId,
} from "@formbricks/lib/membership/service";
-import { verifyUserRoleAccess } from "@formbricks/lib/team/auth";
-import { deleteTeam, updateTeam } from "@formbricks/lib/team/service";
+import { verifyUserRoleAccess } from "@formbricks/lib/organization/auth";
+import { deleteOrganization, updateOrganization } from "@formbricks/lib/organization/service";
import { AuthenticationError, AuthorizationError, ValidationError } from "@formbricks/types/errors";
import { TMembershipRole } from "@formbricks/types/memberships";
-export const updateTeamNameAction = async (teamId: string, teamName: string) => {
+export const updateOrganizationNameAction = async (organizationId: string, organizationName: string) => {
const session = await getServerSession(authOptions);
if (!session) {
throw new AuthenticationError("Not authenticated");
}
- const isUserAuthorized = await hasTeamAuthority(session.user.id, teamId);
+ const isUserAuthorized = await hasOrganizationAuthority(session.user.id, organizationId);
if (!isUserAuthorized) {
throw new AuthenticationError("Not authorized");
}
- return await updateTeam(teamId, { name: teamName });
+ return await updateOrganization(organizationId, { name: organizationName });
};
-export const deleteInviteAction = async (inviteId: string, teamId: string) => {
+export const deleteInviteAction = async (inviteId: string, organizationId: string) => {
const session = await getServerSession(authOptions);
if (!session) {
throw new AuthenticationError("Not authenticated");
}
- const isUserAuthorized = await hasTeamAuthority(session.user.id, teamId);
+ const isUserAuthorized = await hasOrganizationAuthority(session.user.id, organizationId);
if (!isUserAuthorized) {
throw new AuthenticationError("Not authorized");
@@ -48,54 +48,54 @@ export const deleteInviteAction = async (inviteId: string, teamId: string) => {
return await deleteInvite(inviteId);
};
-export const deleteMembershipAction = async (userId: string, teamId: string) => {
+export const deleteMembershipAction = async (userId: string, organizationId: string) => {
const session = await getServerSession(authOptions);
if (!session) {
throw new AuthenticationError("Not authenticated");
}
- const isUserAuthorized = await hasTeamAuthority(session.user.id, teamId);
+ const isUserAuthorized = await hasOrganizationAuthority(session.user.id, organizationId);
if (!isUserAuthorized) {
throw new AuthenticationError("Not authorized");
}
- const { hasDeleteMembersAccess } = await verifyUserRoleAccess(teamId, session.user.id);
+ const { hasDeleteMembersAccess } = await verifyUserRoleAccess(organizationId, session.user.id);
if (!hasDeleteMembersAccess) {
throw new AuthenticationError("Not authorized");
}
if (userId === session.user.id) {
- throw new AuthenticationError("You cannot delete yourself from the team");
+ throw new AuthenticationError("You cannot delete yourself from the organization");
}
- return await deleteMembership(userId, teamId);
+ return await deleteMembership(userId, organizationId);
};
-export const leaveTeamAction = async (teamId: string) => {
+export const leaveOrganizationAction = async (organizationId: string) => {
const session = await getServerSession(authOptions);
if (!session) {
throw new AuthenticationError("Not authenticated");
}
- const membership = await getMembershipByUserIdTeamId(session.user.id, teamId);
+ const membership = await getMembershipByUserIdOrganizationId(session.user.id, organizationId);
if (!membership) {
- throw new AuthenticationError("Not a member of this team");
+ throw new AuthenticationError("Not a member of this organization");
}
if (membership.role === "owner") {
- throw new ValidationError("You cannot leave a team you own");
+ throw new ValidationError("You cannot leave a organization you own");
}
const memberships = await getMembershipsByUserId(session.user.id);
if (!memberships || memberships?.length <= 1) {
- throw new ValidationError("You cannot leave the only team you are a member of");
+ throw new ValidationError("You cannot leave the only organization you are a member of");
}
- await deleteMembership(session.user.id, teamId);
+ await deleteMembership(session.user.id, organizationId);
};
export const createInviteTokenAction = async (inviteId: string) => {
@@ -110,14 +110,14 @@ export const createInviteTokenAction = async (inviteId: string) => {
return { inviteToken: encodeURIComponent(inviteToken) };
};
-export const resendInviteAction = async (inviteId: string, teamId: string) => {
+export const resendInviteAction = async (inviteId: string, organizationId: string) => {
const session = await getServerSession(authOptions);
if (!session) {
throw new AuthenticationError("Not authenticated");
}
- const isUserAuthorized = await hasTeamAuthority(session.user.id, teamId);
+ const isUserAuthorized = await hasOrganizationAuthority(session.user.id, organizationId);
if (INVITE_DISABLED) {
throw new AuthenticationError("Invite disabled");
@@ -127,7 +127,7 @@ export const resendInviteAction = async (inviteId: string, teamId: string) => {
throw new AuthenticationError("Not authorized");
}
- const { hasCreateOrUpdateMembersAccess } = await verifyUserRoleAccess(teamId, session.user.id);
+ const { hasCreateOrUpdateMembersAccess } = await verifyUserRoleAccess(organizationId, session.user.id);
if (!hasCreateOrUpdateMembersAccess) {
throw new AuthenticationError("Not authorized");
}
@@ -143,7 +143,7 @@ export const resendInviteAction = async (inviteId: string, teamId: string) => {
};
export const inviteUserAction = async (
- teamId: string,
+ organizationId: string,
email: string,
name: string,
role: TMembershipRole
@@ -154,7 +154,7 @@ export const inviteUserAction = async (
throw new AuthenticationError("Not authenticated");
}
- const isUserAuthorized = await hasTeamAuthority(session.user.id, teamId);
+ const isUserAuthorized = await hasOrganizationAuthority(session.user.id, organizationId);
if (INVITE_DISABLED) {
throw new AuthenticationError("Invite disabled");
@@ -164,13 +164,13 @@ export const inviteUserAction = async (
throw new AuthenticationError("Not authorized");
}
- const { hasCreateOrUpdateMembersAccess } = await verifyUserRoleAccess(teamId, session.user.id);
+ const { hasCreateOrUpdateMembersAccess } = await verifyUserRoleAccess(organizationId, session.user.id);
if (!hasCreateOrUpdateMembersAccess) {
throw new AuthenticationError("Not authorized");
}
const invite = await inviteUser({
- teamId,
+ organizationId,
currentUser: { id: session.user.id, name: session.user.name },
invitee: {
email,
@@ -186,17 +186,17 @@ export const inviteUserAction = async (
return invite;
};
-export const deleteTeamAction = async (teamId: string) => {
+export const deleteOrganizationAction = async (organizationId: string) => {
const session = await getServerSession(authOptions);
if (!session) {
throw new AuthenticationError("Not authenticated");
}
- const { hasDeleteAccess } = await verifyUserRoleAccess(teamId, session.user.id);
+ const { hasDeleteAccess } = await verifyUserRoleAccess(organizationId, session.user.id);
if (!hasDeleteAccess) {
throw new AuthorizationError("Not authorized");
}
- return await deleteTeam(teamId);
+ return await deleteOrganization(organizationId);
};
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/AddMemberModal.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/AddMemberModal.tsx
similarity index 96%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/AddMemberModal.tsx
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/AddMemberModal.tsx
index c0ee79e0e2..a0b2d57eff 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/AddMemberModal.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/AddMemberModal.tsx
@@ -55,7 +55,7 @@ export const AddMemberModal = ({
open={open}
setOpen={setOpen}
tabs={tabs}
- label={"Invite Team Member"}
+ label={"Invite Organization Member"}
closeOnOutsideClick={true}
/>
>
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/BulkInviteTab.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/BulkInviteTab.tsx
similarity index 97%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/BulkInviteTab.tsx
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/BulkInviteTab.tsx
index f6f073b932..ed44018a7a 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/BulkInviteTab.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/BulkInviteTab.tsx
@@ -89,7 +89,7 @@ export const BulkInviteTab = ({ setOpen, onSubmit, canDoRoleManagement }: BulkIn
- Warning: Please note that on the Free Plan, all team members are
+ Warning: Please note that on the Free Plan, all organization members are
automatically assigned the "Admin" role regardless of the role specified in the CSV
file.
- Permanent removal of all products linked to this team. This includes all surveys,
+ Permanent removal of all products linked to this organization. This includes all surveys,
responses, user actions and attributes associated with these products.
This action cannot be undone. If it's gone, it's gone.
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/EditMemberships/EditMemberships.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/EditMemberships/EditMemberships.tsx
similarity index 73%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/EditMemberships/EditMemberships.tsx
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/EditMemberships/EditMemberships.tsx
index 10257ab894..a21157c86f 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/EditMemberships/EditMemberships.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/EditMemberships/EditMemberships.tsx
@@ -1,29 +1,29 @@
-import { MembersInfo } from "@/app/(app)/environments/[environmentId]/settings/(team)/members/components/EditMemberships/MembersInfo";
+import { MembersInfo } from "@/app/(app)/environments/[environmentId]/settings/(organization)/members/components/EditMemberships/MembersInfo";
import { getRoleManagementPermission } from "@formbricks/ee/lib/service";
-import { getInvitesByTeamId } from "@formbricks/lib/invite/service";
-import { getMembersByTeamId } from "@formbricks/lib/membership/service";
+import { getInvitesByOrganizationId } from "@formbricks/lib/invite/service";
+import { getMembersByOrganizationId } from "@formbricks/lib/membership/service";
import { TMembership } from "@formbricks/types/memberships";
-import { TTeam } from "@formbricks/types/teams";
+import { TOrganization } from "@formbricks/types/organizations";
type EditMembershipsProps = {
- team: TTeam;
+ organization: TOrganization;
currentUserId: string;
currentUserMembership: TMembership;
allMemberships: TMembership[];
};
export const EditMemberships = async ({
- team,
+ organization,
currentUserId,
currentUserMembership: membership,
}: EditMembershipsProps) => {
- const members = await getMembersByTeamId(team.id);
- const invites = await getInvitesByTeamId(team.id);
+ const members = await getMembersByOrganizationId(organization.id);
+ const invites = await getInvitesByOrganizationId(organization.id);
const currentUserRole = membership?.role;
const isUserAdminOrOwner = membership?.role === "admin" || membership?.role === "owner";
- const canDoRoleManagement = await getRoleManagementPermission(team);
+ const canDoRoleManagement = await getRoleManagementPermission(organization);
return (
- You cannot leave this team as it is your only team. Create a new team first.
+ You cannot leave this organization as it is your only organization. Create a new organization
+ first.
+ ) : (
+
+ );
+};
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/IndividualInviteTab.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/IndividualInviteTab.tsx
similarity index 100%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/IndividualInviteTab.tsx
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/IndividualInviteTab.tsx
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/ShareInviteModal.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/ShareInviteModal.tsx
similarity index 90%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/ShareInviteModal.tsx
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/ShareInviteModal.tsx
index 646fefe7b5..b8b687112d 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/components/ShareInviteModal.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/components/ShareInviteModal.tsx
@@ -36,9 +36,13 @@ export const ShareInviteModal = ({ inviteToken, open, setOpen }: ShareInviteModa
-
Your team invite link is ready!
+
+ Your organization invite link is ready!
+
-
Share this link to let your team member join your team:
+
+ Share this link to let your organization member join your organization:
+
{
const cards = [
{
title: "Manage members",
- description: "Add or remove members in your team",
+ description: "Add or remove members in your organization",
skeleton: (
@@ -47,8 +47,8 @@ const Loading = () => {
),
},
{
- title: "Team Name",
- description: "Give your team a descriptive name",
+ title: "Organization Name",
+ description: "Give your organization a descriptive name",
skeleton: (
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/page.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/page.tsx
similarity index 66%
rename from apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/page.tsx
rename to apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/page.tsx
index faf9fb253c..dc843d6443 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/(team)/members/page.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/(organization)/members/page.tsx
@@ -1,23 +1,26 @@
-import { TeamSettingsNavbar } from "@/app/(app)/environments/[environmentId]/settings/(team)/components/TeamSettingsNavbar";
-import { TeamActions } from "@/app/(app)/environments/[environmentId]/settings/(team)/members/components/EditMemberships/TeamActions";
+import { OrganizationSettingsNavbar } from "@/app/(app)/environments/[environmentId]/settings/(organization)/components/OrganizationSettingsNavbar";
+import { OrganizationActions } from "@/app/(app)/environments/[environmentId]/settings/(organization)/members/components/EditMemberships/OrganizationActions";
import { getServerSession } from "next-auth";
import { Suspense } from "react";
import { getRoleManagementPermission } from "@formbricks/ee/lib/service";
import { authOptions } from "@formbricks/lib/authOptions";
import { INVITE_DISABLED, IS_FORMBRICKS_CLOUD } from "@formbricks/lib/constants";
-import { getMembershipByUserIdTeamId, getMembershipsByUserId } from "@formbricks/lib/membership/service";
+import {
+ getMembershipByUserIdOrganizationId,
+ getMembershipsByUserId,
+} from "@formbricks/lib/membership/service";
import { getAccessFlags } from "@formbricks/lib/membership/utils";
-import { getTeamByEnvironmentId } from "@formbricks/lib/team/service";
+import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
import { PageContentWrapper } from "@formbricks/ui/PageContentWrapper";
import { PageHeader } from "@formbricks/ui/PageHeader";
import { SettingsId } from "@formbricks/ui/SettingsId";
import { Skeleton } from "@formbricks/ui/Skeleton";
import { SettingsCard } from "../../components/SettingsCard";
-import { DeleteTeam } from "./components/DeleteTeam";
+import { DeleteOrganization } from "./components/DeleteOrganization";
import { EditMemberships } from "./components/EditMemberships";
-import { EditTeamName } from "./components/EditTeamName";
+import { EditOrganizationName } from "./components/EditOrganizationName";
const MembersLoading = () => (
- ) : (
-
- );
-};
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/components/ResponseTimeline.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/components/ResponseTimeline.tsx
index 50a3546377..dfa7349442 100644
--- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/components/ResponseTimeline.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/components/ResponseTimeline.tsx
@@ -3,7 +3,7 @@
import { EmptyAppSurveys } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/components/EmptyInAppSurveys";
import { useEffect, useRef, useState } from "react";
-import { getMembershipByUserIdTeamIdAction } from "@formbricks/lib/membership/hooks/actions";
+import { getMembershipByUserIdOrganizationIdAction } from "@formbricks/lib/membership/hooks/actions";
import { getAccessFlags } from "@formbricks/lib/membership/utils";
import { TEnvironment } from "@formbricks/types/environment";
import { TResponse } from "@formbricks/types/responses";
@@ -76,7 +76,7 @@ export const ResponseTimeline = ({
const getRole = async () => {
if (isSharingPage) return setIsViewer(true);
- const membershipRole = await getMembershipByUserIdTeamIdAction(survey.environmentId);
+ const membershipRole = await getMembershipByUserIdOrganizationIdAction(survey.environmentId);
const { isViewer } = getAccessFlags(membershipRole);
setIsViewer(isViewer);
};
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/page.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/page.tsx
index 47c5b7523c..fd527d4f1d 100644
--- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/page.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/page.tsx
@@ -6,13 +6,13 @@ import { getServerSession } from "next-auth";
import { authOptions } from "@formbricks/lib/authOptions";
import { RESPONSES_PER_PAGE, WEBAPP_URL } from "@formbricks/lib/constants";
import { getEnvironment } from "@formbricks/lib/environment/service";
-import { getMembershipByUserIdTeamId } from "@formbricks/lib/membership/service";
+import { getMembershipByUserIdOrganizationId } from "@formbricks/lib/membership/service";
import { getAccessFlags } from "@formbricks/lib/membership/utils";
+import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
import { getResponseCountBySurveyId } from "@formbricks/lib/response/service";
import { getSurvey } from "@formbricks/lib/survey/service";
import { getTagsByEnvironmentId } from "@formbricks/lib/tag/service";
-import { getTeamByEnvironmentId } from "@formbricks/lib/team/service";
import { getUser } from "@formbricks/lib/user/service";
import { PageContentWrapper } from "@formbricks/ui/PageContentWrapper";
import { PageHeader } from "@formbricks/ui/PageHeader";
@@ -43,13 +43,13 @@ const Page = async ({ params }) => {
throw new Error("User not found");
}
const tags = await getTagsByEnvironmentId(params.environmentId);
- const team = await getTeamByEnvironmentId(params.environmentId);
+ const organization = await getOrganizationByEnvironmentId(params.environmentId);
- if (!team) {
- throw new Error("Team not found");
+ if (!organization) {
+ throw new Error("Organization not found");
}
- const currentUserMembership = await getMembershipByUserIdTeamId(session?.user.id, team.id);
+ const currentUserMembership = await getMembershipByUserIdOrganizationId(session?.user.id, organization.id);
const totalResponseCount = await getResponseCountBySurveyId(params.surveyId);
const { isViewer } = getAccessFlags(currentUserMembership?.role);
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/ShareSurveyResults.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/ShareSurveyResults.tsx
index 5b905c67c3..012d9fb263 100644
--- a/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/ShareSurveyResults.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/ShareSurveyResults.tsx
@@ -81,8 +81,8 @@ export const ShareSurveyResults = ({
You are about to release these survey results to the public.
- Your survey results will be public. Anyone outside your team can access them if they have the
- link.
+ Your survey results will be public. Anyone outside your organization can access them if they
+ have the link.
diff --git a/apps/web/app/(app)/onboarding/components/onboarding.tsx b/apps/web/app/(app)/onboarding/components/onboarding.tsx
index 5997a5c6f9..ca4593c042 100644
--- a/apps/web/app/(app)/onboarding/components/onboarding.tsx
+++ b/apps/web/app/(app)/onboarding/components/onboarding.tsx
@@ -3,7 +3,7 @@
import jsPackageJson from "@/../../packages/js/package.json";
import { finishOnboardingAction } from "@/app/(app)/onboarding/actions";
import { ConnectWithFormbricks } from "@/app/(app)/onboarding/components/inapp/ConnectWithFormbricks";
-import { InviteTeamMate } from "@/app/(app)/onboarding/components/inapp/InviteTeamMate";
+import { InviteOrganizationMember } from "@/app/(app)/onboarding/components/inapp/InviteOrganizationMate";
import { Objective } from "@/app/(app)/onboarding/components/inapp/SurveyObjective";
import { Role } from "@/app/(app)/onboarding/components/inapp/SurveyRole";
import { CreateFirstSurvey } from "@/app/(app)/onboarding/components/link/CreateFirstSurvey";
@@ -12,7 +12,7 @@ import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { TEnvironment } from "@formbricks/types/environment";
-import { TTeam } from "@formbricks/types/teams";
+import { TOrganization } from "@formbricks/types/organizations";
import { TUser } from "@formbricks/types/user";
import { PathwaySelect } from "./PathwaySelect";
@@ -23,7 +23,7 @@ interface OnboardingProps {
session: Session;
environment: TEnvironment;
user: TUser;
- team: TTeam;
+ organization: TOrganization;
webAppUrl: string;
}
@@ -32,7 +32,7 @@ export const Onboarding = ({
session,
environment,
user,
- team,
+ organization,
webAppUrl,
}: OnboardingProps) => {
const router = useRouter();
@@ -140,7 +140,11 @@ export const Onboarding = ({
return selectedPathway === "link" ? (
) : (
-
+
);
default:
return null;
diff --git a/apps/web/app/(app)/onboarding/page.tsx b/apps/web/app/(app)/onboarding/page.tsx
index e72b9bf21e..793da3afe6 100644
--- a/apps/web/app/(app)/onboarding/page.tsx
+++ b/apps/web/app/(app)/onboarding/page.tsx
@@ -5,7 +5,7 @@ import { redirect } from "next/navigation";
import { authOptions } from "@formbricks/lib/authOptions";
import { IS_FORMBRICKS_CLOUD, WEBAPP_URL } from "@formbricks/lib/constants";
import { getFirstEnvironmentByUserId } from "@formbricks/lib/environment/service";
-import { getTeamByEnvironmentId } from "@formbricks/lib/team/service";
+import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
import { getUser } from "@formbricks/lib/user/service";
const Page = async () => {
@@ -24,11 +24,11 @@ const Page = async () => {
const userId = session.user.id;
const environment = await getFirstEnvironmentByUserId(userId);
const user = await getUser(userId);
- const team = environment ? await getTeamByEnvironmentId(environment.id) : null;
+ const organization = environment ? await getOrganizationByEnvironmentId(environment.id) : null;
// Ensure all necessary data is available
- if (!environment || !user || !team) {
- throw new Error("Failed to get necessary user, environment, or team information");
+ if (!environment || !user || !organization) {
+ throw new Error("Failed to get necessary user, environment, or organization information");
}
return (
@@ -37,7 +37,7 @@ const Page = async () => {
session={session}
environment={environment}
user={user}
- team={team}
+ organization={organization}
webAppUrl={WEBAPP_URL}
/>
);
diff --git a/apps/web/app/(auth)/invite/components/InviteContentComponents.tsx b/apps/web/app/(auth)/invite/components/InviteContentComponents.tsx
index ce541d6c99..66bb007d38 100644
--- a/apps/web/app/(auth)/invite/components/InviteContentComponents.tsx
+++ b/apps/web/app/(auth)/invite/components/InviteContentComponents.tsx
@@ -51,7 +51,7 @@ export const WrongAccountContent = () => {
export const RightAccountContent = () => {
return (
-
+
Go to app
diff --git a/apps/web/app/(auth)/invite/page.tsx b/apps/web/app/(auth)/invite/page.tsx
index aac7801d0d..064506e4ce 100644
--- a/apps/web/app/(auth)/invite/page.tsx
+++ b/apps/web/app/(auth)/invite/page.tsx
@@ -41,7 +41,7 @@ const Page = async ({ searchParams }) => {
} else if (session.user?.email !== email) {
return ;
} else {
- await createMembership(invite.teamId, session.user.id, { accepted: true, role: invite.role });
+ await createMembership(invite.organizationId, session.user.id, { accepted: true, role: invite.role });
await deleteInvite(inviteId);
sendInviteAcceptedEmail(invite.creator.name ?? "", session.user?.name ?? "", invite.creator.email);
diff --git a/apps/web/app/(redirects)/teams/[teamId]/route.ts b/apps/web/app/(redirects)/organizations/[organizationId]/route.ts
similarity index 71%
rename from apps/web/app/(redirects)/teams/[teamId]/route.ts
rename to apps/web/app/(redirects)/organizations/[organizationId]/route.ts
index 730c8197df..a39e0e5008 100644
--- a/apps/web/app/(redirects)/teams/[teamId]/route.ts
+++ b/apps/web/app/(redirects)/organizations/[organizationId]/route.ts
@@ -1,4 +1,4 @@
-import { hasTeamAccess } from "@/app/lib/api/apiHelper";
+import { hasOrganizationAccess } from "@/app/lib/api/apiHelper";
import { getServerSession } from "next-auth";
import { redirect } from "next/navigation";
import { notFound } from "next/navigation";
@@ -8,16 +8,16 @@ import { getEnvironments } from "@formbricks/lib/environment/service";
import { getProducts } from "@formbricks/lib/product/service";
import { AuthenticationError, AuthorizationError } from "@formbricks/types/errors";
-export const GET = async (_: Request, context: { params: { teamId: string } }) => {
- const teamId = context?.params?.teamId;
- if (!teamId) return notFound();
+export const GET = async (_: Request, context: { params: { organizationId: string } }) => {
+ const organizationId = context?.params?.organizationId;
+ if (!organizationId) return notFound();
// check auth
const session = await getServerSession(authOptions);
if (!session) throw new AuthenticationError("Not authenticated");
- const hasAccess = await hasTeamAccess(session.user, teamId);
+ const hasAccess = await hasOrganizationAccess(session.user, organizationId);
if (!hasAccess) throw new AuthorizationError("Unauthorized");
// redirect to first product's production environment
- const products = await getProducts(teamId);
+ const products = await getProducts(organizationId);
if (products.length === 0) return notFound();
const firstProduct = products[0];
const environments = await getEnvironments(firstProduct.id);
diff --git a/apps/web/app/(redirects)/products/[productId]/route.ts b/apps/web/app/(redirects)/products/[productId]/route.ts
index 11b08500c6..d0e915d59c 100644
--- a/apps/web/app/(redirects)/products/[productId]/route.ts
+++ b/apps/web/app/(redirects)/products/[productId]/route.ts
@@ -1,4 +1,4 @@
-import { hasTeamAccess } from "@/app/lib/api/apiHelper";
+import { hasOrganizationAccess } from "@/app/lib/api/apiHelper";
import { getServerSession } from "next-auth";
import { notFound, redirect } from "next/navigation";
@@ -15,7 +15,7 @@ export const GET = async (_: Request, context: { params: { productId: string } }
if (!session) throw new AuthenticationError("Not authenticated");
const product = await getProduct(productId);
if (!product) return notFound();
- const hasAccess = await hasTeamAccess(session.user, product.teamId);
+ const hasAccess = await hasOrganizationAccess(session.user, product.organizationId);
if (!hasAccess) throw new AuthorizationError("Unauthorized");
// redirect to product's production environment
const environments = await getEnvironments(product.id);
diff --git a/apps/web/app/api/cron/report-usage/route.ts b/apps/web/app/api/cron/report-usage/route.ts
index f837103634..005cdb68b4 100644
--- a/apps/web/app/api/cron/report-usage/route.ts
+++ b/apps/web/app/api/cron/report-usage/route.ts
@@ -5,14 +5,14 @@ import { ProductFeatureKeys } from "@formbricks/ee/billing/lib/constants";
import { reportUsageToStripe } from "@formbricks/ee/billing/lib/reportUsage";
import { CRON_SECRET, IS_FORMBRICKS_CLOUD } from "@formbricks/lib/constants";
import {
- getMonthlyActiveTeamPeopleCount,
- getMonthlyTeamResponseCount,
- getTeamsWithPaidPlan,
-} from "@formbricks/lib/team/service";
-import { TTeam } from "@formbricks/types/teams";
+ getMonthlyActiveOrganizationPeopleCount,
+ getMonthlyOrganizationResponseCount,
+ getOrganizationsWithPaidPlan,
+} from "@formbricks/lib/organization/service";
+import { TOrganization } from "@formbricks/types/organizations";
-const reportTeamUsage = async (team: TTeam) => {
- const stripeCustomerId = team.billing.stripeCustomerId;
+const reportOrganizationUsage = async (organization: TOrganization) => {
+ const stripeCustomerId = organization.billing.stripeCustomerId;
if (!stripeCustomerId) {
return;
}
@@ -22,16 +22,17 @@ const reportTeamUsage = async (team: TTeam) => {
}
let calculateResponses =
- team.billing.features.inAppSurvey.status !== "inactive" && !team.billing.features.inAppSurvey.unlimited;
+ organization.billing.features.inAppSurvey.status !== "inactive" &&
+ !organization.billing.features.inAppSurvey.unlimited;
let calculatePeople =
- team.billing.features.userTargeting.status !== "inactive" &&
- !team.billing.features.userTargeting.unlimited;
+ organization.billing.features.userTargeting.status !== "inactive" &&
+ !organization.billing.features.userTargeting.unlimited;
if (!calculatePeople && !calculateResponses) {
return;
}
- let people = await getMonthlyActiveTeamPeopleCount(team.id);
- let responses = await getMonthlyTeamResponseCount(team.id);
+ let people = await getMonthlyActiveOrganizationPeopleCount(organization.id);
+ let responses = await getMonthlyOrganizationResponseCount(organization.id);
if (calculatePeople) {
await reportUsageToStripe(
@@ -60,8 +61,8 @@ export const POST = async (): Promise => {
}
try {
- const teamsWithPaidPlan = await getTeamsWithPaidPlan();
- await Promise.all(teamsWithPaidPlan.map(reportTeamUsage));
+ const organizationsWithPaidPlan = await getOrganizationsWithPaidPlan();
+ await Promise.all(organizationsWithPaidPlan.map(reportOrganizationUsage));
return responses.successResponse({}, true);
} catch (error) {
diff --git a/apps/web/app/api/cron/weekly-summary/route.ts b/apps/web/app/api/cron/weekly-summary/route.ts
index 3549489247..b7a6427620 100644
--- a/apps/web/app/api/cron/weekly-summary/route.ts
+++ b/apps/web/app/api/cron/weekly-summary/route.ts
@@ -25,41 +25,43 @@ export const POST = async (): Promise => {
const emailSendingPromises: Promise[] = [];
- // Fetch all team IDs
- const teamIds = await getTeamIds();
+ // Fetch all organization IDs
+ const organizationIds = await getOrganizationIds();
- // Paginate through teams
- for (let i = 0; i < teamIds.length; i += BATCH_SIZE) {
- const batchedTeamIds = teamIds.slice(i, i + BATCH_SIZE);
- // Fetch products for batched teams asynchronously
- const batchedProductsPromises = batchedTeamIds.map((teamId) => getProductsByTeamId(teamId));
+ // Paginate through organizations
+ for (let i = 0; i < organizationIds.length; i += BATCH_SIZE) {
+ const batchedOrganizationIds = organizationIds.slice(i, i + BATCH_SIZE);
+ // Fetch products for batched organizations asynchronously
+ const batchedProductsPromises = batchedOrganizationIds.map((organizationId) =>
+ getProductsByOrganizationId(organizationId)
+ );
const batchedProducts = await Promise.all(batchedProductsPromises);
for (const products of batchedProducts) {
for (const product of products) {
- const teamMembers = product.team.memberships;
- const teamMembersWithNotificationEnabled = teamMembers.filter(
+ const organizationMembers = product.organization.memberships;
+ const organizationMembersWithNotificationEnabled = organizationMembers.filter(
(member) =>
member.user.notificationSettings?.weeklySummary &&
member.user.notificationSettings.weeklySummary[product.id]
);
- if (teamMembersWithNotificationEnabled.length === 0) continue;
+ if (organizationMembersWithNotificationEnabled.length === 0) continue;
const notificationResponse = getNotificationResponse(product.environments[0], product.name);
if (notificationResponse.insights.numLiveSurvey === 0) {
- for (const teamMember of teamMembersWithNotificationEnabled) {
+ for (const organizationMember of organizationMembersWithNotificationEnabled) {
emailSendingPromises.push(
- sendNoLiveSurveyNotificationEmail(teamMember.user.email, notificationResponse)
+ sendNoLiveSurveyNotificationEmail(organizationMember.user.email, notificationResponse)
);
}
continue;
}
- for (const teamMember of teamMembersWithNotificationEnabled) {
+ for (const organizationMember of organizationMembersWithNotificationEnabled) {
emailSendingPromises.push(
- sendWeeklySummaryNotificationEmail(teamMember.user.email, notificationResponse)
+ sendWeeklySummaryNotificationEmail(organizationMember.user.email, notificationResponse)
);
}
}
@@ -70,22 +72,22 @@ export const POST = async (): Promise => {
return responses.successResponse({}, true);
};
-const getTeamIds = async (): Promise => {
- const teams = await prisma.team.findMany({
+const getOrganizationIds = async (): Promise => {
+ const organizations = await prisma.organization.findMany({
select: {
id: true,
},
});
- return teams.map((team) => team.id);
+ return organizations.map((organization) => organization.id);
};
-const getProductsByTeamId = async (teamId: string): Promise => {
+const getProductsByOrganizationId = async (organizationId: string): Promise => {
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
return await prisma.product.findMany({
where: {
- teamId: teamId,
+ organizationId: organizationId,
},
select: {
id: true,
@@ -152,7 +154,7 @@ const getProductsByTeamId = async (teamId: string): Promise {
if (event === "responseFinished") {
// check for email notifications
- // get all users that have a membership of this environment's team
+ // get all users that have a membership of this environment's organization
const users = await prisma.user.findMany({
where: {
memberships: {
some: {
- team: {
+ organization: {
products: {
some: {
environments: {
diff --git a/apps/web/app/api/v1/(legacy)/client/[environmentId]/people/[userId]/set-attribute/route.ts b/apps/web/app/api/v1/(legacy)/client/[environmentId]/people/[userId]/set-attribute/route.ts
index f71c297b38..35f2d6dc48 100644
--- a/apps/web/app/api/v1/(legacy)/client/[environmentId]/people/[userId]/set-attribute/route.ts
+++ b/apps/web/app/api/v1/(legacy)/client/[environmentId]/people/[userId]/set-attribute/route.ts
@@ -3,12 +3,12 @@ import { transformErrorToDetails } from "@/app/lib/api/validator";
import { getActionClasses } from "@formbricks/lib/actionClass/service";
import { updateAttributes } from "@formbricks/lib/attribute/service";
+import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
import { personCache } from "@formbricks/lib/person/cache";
import { getPerson } from "@formbricks/lib/person/service";
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
import { surveyCache } from "@formbricks/lib/survey/cache";
import { getSyncSurveys } from "@formbricks/lib/survey/service";
-import { getTeamByEnvironmentId } from "@formbricks/lib/team/service";
import { ZJsPeopleAttributeInput } from "@formbricks/types/js";
interface Context {
@@ -58,10 +58,10 @@ export const POST = async (req: Request, context: Context): Promise =>
environmentId,
});
- const team = await getTeamByEnvironmentId(environmentId);
+ const organization = await getOrganizationByEnvironmentId(environmentId);
- if (!team) {
- throw new Error("Team not found");
+ if (!organization) {
+ throw new Error("Organization not found");
}
const [surveys, noCodeActionClasses, product] = await Promise.all([
diff --git a/apps/web/app/api/v1/(legacy)/client/people/[personId]/set-attribute/route.ts b/apps/web/app/api/v1/(legacy)/client/people/[personId]/set-attribute/route.ts
index b852651ef2..ab08ccb989 100644
--- a/apps/web/app/api/v1/(legacy)/client/people/[personId]/set-attribute/route.ts
+++ b/apps/web/app/api/v1/(legacy)/client/people/[personId]/set-attribute/route.ts
@@ -3,12 +3,12 @@ import { transformErrorToDetails } from "@/app/lib/api/validator";
import { getActionClasses } from "@formbricks/lib/actionClass/service";
import { updateAttributes } from "@formbricks/lib/attribute/service";
+import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
import { personCache } from "@formbricks/lib/person/cache";
import { getPerson } from "@formbricks/lib/person/service";
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
import { surveyCache } from "@formbricks/lib/survey/cache";
import { getSyncSurveys } from "@formbricks/lib/survey/service";
-import { getTeamByEnvironmentId } from "@formbricks/lib/team/service";
import { ZJsPeopleAttributeInput } from "@formbricks/types/js";
interface Context {
@@ -57,10 +57,10 @@ export const POST = async (req: Request, context: Context): Promise =>
environmentId,
});
- const team = await getTeamByEnvironmentId(environmentId);
+ const organization = await getOrganizationByEnvironmentId(environmentId);
- if (!team) {
- throw new Error("Team not found");
+ if (!organization) {
+ throw new Error("Organization not found");
}
const [surveys, noCodeActionClasses, product] = await Promise.all([
diff --git a/apps/web/app/api/v1/(legacy)/js/sync/lib/sync.ts b/apps/web/app/api/v1/(legacy)/js/sync/lib/sync.ts
index 913810fddd..10f7eacf2c 100644
--- a/apps/web/app/api/v1/(legacy)/js/sync/lib/sync.ts
+++ b/apps/web/app/api/v1/(legacy)/js/sync/lib/sync.ts
@@ -7,15 +7,15 @@ import {
} from "@formbricks/lib/constants";
import { getEnvironment } from "@formbricks/lib/environment/service";
import { reverseTranslateSurvey } from "@formbricks/lib/i18n/reverseTranslation";
+import {
+ getMonthlyActiveOrganizationPeopleCount,
+ getMonthlyOrganizationResponseCount,
+ getOrganizationByEnvironmentId,
+} from "@formbricks/lib/organization/service";
import { getPerson } from "@formbricks/lib/person/service";
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
import { COLOR_DEFAULTS } from "@formbricks/lib/styling/constants";
import { getSurveys, getSyncSurveys } from "@formbricks/lib/survey/service";
-import {
- getMonthlyActiveTeamPeopleCount,
- getMonthlyTeamResponseCount,
- getTeamByEnvironmentId,
-} from "@formbricks/lib/team/service";
import { TEnvironment } from "@formbricks/types/environment";
import { TJsLegacyState, TSurveyWithTriggers } from "@formbricks/types/js";
import { TPerson } from "@formbricks/types/people";
@@ -43,19 +43,19 @@ export const getUpdatedState = async (environmentId: string, personId?: string):
throw new Error("Environment does not exist");
}
- // check team subscriptons
- const team = await getTeamByEnvironmentId(environmentId);
+ // check organization subscriptons
+ const organization = await getOrganizationByEnvironmentId(environmentId);
- if (!team) {
- throw new Error("Team does not exist");
+ if (!organization) {
+ throw new Error("Organization does not exist");
}
// check if Monthly Active Users limit is reached
if (IS_FORMBRICKS_CLOUD) {
const hasUserTargetingSubscription =
- team?.billing?.features.userTargeting.status &&
- ["active", "canceled"].includes(team?.billing?.features.userTargeting.status);
- const currentMau = await getMonthlyActiveTeamPeopleCount(team.id);
+ organization?.billing?.features.userTargeting.status &&
+ ["active", "canceled"].includes(organization?.billing?.features.userTargeting.status);
+ const currentMau = await getMonthlyActiveOrganizationPeopleCount(organization.id);
const isMauLimitReached = !hasUserTargetingSubscription && currentMau >= PRICING_USERTARGETING_FREE_MTU;
if (isMauLimitReached) {
const errorMessage = `Monthly Active Users limit reached in ${environmentId} (${currentMau}/${MAU_LIMIT})`;
@@ -82,9 +82,9 @@ export const getUpdatedState = async (environmentId: string, personId?: string):
let isAppSurveyLimitReached = false;
if (IS_FORMBRICKS_CLOUD) {
const hasAppSurveySubscription =
- team?.billing?.features.inAppSurvey.status &&
- ["active", "canceled"].includes(team?.billing?.features.inAppSurvey.status);
- const monthlyResponsesCount = await getMonthlyTeamResponseCount(team.id);
+ organization?.billing?.features.inAppSurvey.status &&
+ ["active", "canceled"].includes(organization?.billing?.features.inAppSurvey.status);
+ const monthlyResponsesCount = await getMonthlyOrganizationResponseCount(organization.id);
isAppSurveyLimitReached =
IS_FORMBRICKS_CLOUD &&
!hasAppSurveySubscription &&
diff --git a/apps/web/app/api/v1/client/[environmentId]/actions/route.ts b/apps/web/app/api/v1/client/[environmentId]/actions/route.ts
index c34583cf93..e81febe032 100644
--- a/apps/web/app/api/v1/client/[environmentId]/actions/route.ts
+++ b/apps/web/app/api/v1/client/[environmentId]/actions/route.ts
@@ -3,7 +3,7 @@ import { transformErrorToDetails } from "@/app/lib/api/validator";
import { createAction } from "@formbricks/lib/action/service";
import { IS_FORMBRICKS_CLOUD } from "@formbricks/lib/constants";
-import { getTeamByEnvironmentId } from "@formbricks/lib/team/service";
+import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
import { ZActionInput } from "@formbricks/types/actions";
interface Context {
@@ -36,8 +36,8 @@ export const POST = async (req: Request, context: Context): Promise =>
// Formbricks Cloud: Make sure environment is part of a paid plan
if (IS_FORMBRICKS_CLOUD) {
- const team = await getTeamByEnvironmentId(context.params.environmentId);
- if (!team || team.billing.features.userTargeting.status !== "active") {
+ const organization = await getOrganizationByEnvironmentId(context.params.environmentId);
+ if (!organization || organization.billing.features.userTargeting.status !== "active") {
// temporary return status code 200 to avoid CORS issues; will be changed to 400 in the future
return responses.successResponse({}, true);
//return responses.badRequestResponse("Storing actions is only possible in a paid plan", {}, true);
diff --git a/apps/web/app/api/v1/client/[environmentId]/app/sync/[userId]/route.ts b/apps/web/app/api/v1/client/[environmentId]/app/sync/[userId]/route.ts
index 247506f96d..d9513736a8 100644
--- a/apps/web/app/api/v1/client/[environmentId]/app/sync/[userId]/route.ts
+++ b/apps/web/app/api/v1/client/[environmentId]/app/sync/[userId]/route.ts
@@ -11,15 +11,15 @@ import {
PRICING_USERTARGETING_FREE_MTU,
} from "@formbricks/lib/constants";
import { getEnvironment, updateEnvironment } from "@formbricks/lib/environment/service";
+import {
+ getMonthlyActiveOrganizationPeopleCount,
+ getMonthlyOrganizationResponseCount,
+ getOrganizationByEnvironmentId,
+} from "@formbricks/lib/organization/service";
import { createPerson, getIsPersonMonthlyActive, getPersonByUserId } from "@formbricks/lib/person/service";
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
import { COLOR_DEFAULTS } from "@formbricks/lib/styling/constants";
import { getSyncSurveys, transformToLegacySurvey } from "@formbricks/lib/survey/service";
-import {
- getMonthlyActiveTeamPeopleCount,
- getMonthlyTeamResponseCount,
- getTeamByEnvironmentId,
-} from "@formbricks/lib/team/service";
import { isVersionGreaterThanOrEqualTo } from "@formbricks/lib/utils/version";
import { TLegacySurvey } from "@formbricks/types/LegacySurvey";
import { TEnvironment } from "@formbricks/types/environment";
@@ -75,11 +75,11 @@ export const GET = async (
await updateEnvironment(environment.id, { widgetSetupCompleted: true });
}
- // check team subscriptions
- const team = await getTeamByEnvironmentId(environmentId);
+ // check organization subscriptions
+ const organization = await getOrganizationByEnvironmentId(environmentId);
- if (!team) {
- throw new Error("Team does not exist");
+ if (!organization) {
+ throw new Error("Organization does not exist");
}
// check if MAU limit is reached
@@ -88,15 +88,15 @@ export const GET = async (
if (IS_FORMBRICKS_CLOUD) {
// check userTargeting subscription
const hasUserTargetingSubscription =
- team.billing.features.userTargeting.status &&
- ["active", "canceled"].includes(team.billing.features.userTargeting.status);
- const currentMau = await getMonthlyActiveTeamPeopleCount(team.id);
+ organization.billing.features.userTargeting.status &&
+ ["active", "canceled"].includes(organization.billing.features.userTargeting.status);
+ const currentMau = await getMonthlyActiveOrganizationPeopleCount(organization.id);
isMauLimitReached = !hasUserTargetingSubscription && currentMau >= PRICING_USERTARGETING_FREE_MTU;
// check inAppSurvey subscription
const hasInAppSurveySubscription =
- team.billing.features.inAppSurvey.status &&
- ["active", "canceled"].includes(team.billing.features.inAppSurvey.status);
- const currentResponseCount = await getMonthlyTeamResponseCount(team.id);
+ organization.billing.features.inAppSurvey.status &&
+ ["active", "canceled"].includes(organization.billing.features.inAppSurvey.status);
+ const currentResponseCount = await getMonthlyOrganizationResponseCount(organization.id);
isInAppSurveyLimitReached =
!hasInAppSurveySubscription && currentResponseCount >= PRICING_APPSURVEYS_FREE_RESPONSES;
}
diff --git a/apps/web/app/api/v1/client/[environmentId]/storage/local/route.ts b/apps/web/app/api/v1/client/[environmentId]/storage/local/route.ts
index 3e8e4f1cb2..7a98029048 100644
--- a/apps/web/app/api/v1/client/[environmentId]/storage/local/route.ts
+++ b/apps/web/app/api/v1/client/[environmentId]/storage/local/route.ts
@@ -7,9 +7,9 @@ import { NextRequest } from "next/server";
import { ENCRYPTION_KEY, UPLOADS_DIR } from "@formbricks/lib/constants";
import { validateLocalSignedUrl } from "@formbricks/lib/crypto";
+import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
import { putFileToLocalStorage } from "@formbricks/lib/storage/service";
import { getSurvey } from "@formbricks/lib/survey/service";
-import { getTeamByEnvironmentId } from "@formbricks/lib/team/service";
interface Context {
params: {
@@ -69,14 +69,17 @@ export const POST = async (req: NextRequest, context: Context): Promise= PRICING_APPSURVEYS_FREE_RESPONSES;
if (isInAppSurveyLimitReached) {
diff --git a/apps/web/app/api/v1/users/me/route.ts b/apps/web/app/api/v1/users/me/route.ts
index f2582340e4..fc997b46bc 100644
--- a/apps/web/app/api/v1/users/me/route.ts
+++ b/apps/web/app/api/v1/users/me/route.ts
@@ -53,12 +53,12 @@ const deleteUser = async (userId: string) => {
});
};
-const updateUserMembership = async (teamId: string, userId: string, role: MembershipRole) => {
+const updateUserMembership = async (organizationId: string, userId: string, role: MembershipRole) => {
await prisma.membership.update({
where: {
- userId_teamId: {
+ userId_organizationId: {
userId,
- teamId,
+ organizationId,
},
},
data: {
@@ -70,10 +70,10 @@ const updateUserMembership = async (teamId: string, userId: string, role: Member
const getAdminMemberships = (memberships: Membership[]) =>
memberships.filter((membership) => membership.role === MembershipRole.admin);
-const deleteTeam = async (teamId: string) => {
- await prisma.team.delete({
+const deleteOrganization = async (organizationId: string) => {
+ await prisma.organization.delete({
where: {
- id: teamId,
+ id: organizationId,
},
});
};
@@ -93,7 +93,7 @@ export const DELETE = async () => {
userId: currentUser.id,
},
include: {
- team: {
+ organization: {
select: {
id: true,
name: true,
@@ -109,22 +109,22 @@ export const DELETE = async () => {
});
for (const currentUserMembership of currentUserMemberships) {
- const teamMemberships = currentUserMembership.team.memberships;
+ const organizationMemberships = currentUserMembership.organization.memberships;
const role = currentUserMembership.role;
- const teamId = currentUserMembership.teamId;
+ const organizationId = currentUserMembership.organizationId;
- const teamAdminMemberships = getAdminMemberships(teamMemberships);
- const teamHasAtLeastOneAdmin = teamAdminMemberships.length > 0;
- const teamHasOnlyOneMember = teamMemberships.length === 1;
- const currentUserIsTeamOwner = role === MembershipRole.owner;
+ const organizationAdminMemberships = getAdminMemberships(organizationMemberships);
+ const organizationHasAtLeastOneAdmin = organizationAdminMemberships.length > 0;
+ const organizationHasOnlyOneMember = organizationMemberships.length === 1;
+ const currentUserIsOrganizationOwner = role === MembershipRole.owner;
- if (teamHasOnlyOneMember) {
- await deleteTeam(teamId);
- } else if (currentUserIsTeamOwner && teamHasAtLeastOneAdmin) {
- const firstAdmin = teamAdminMemberships[0];
- await updateUserMembership(teamId, firstAdmin.userId, MembershipRole.owner);
- } else if (currentUserIsTeamOwner) {
- await deleteTeam(teamId);
+ if (organizationHasOnlyOneMember) {
+ await deleteOrganization(organizationId);
+ } else if (currentUserIsOrganizationOwner && organizationHasAtLeastOneAdmin) {
+ const firstAdmin = organizationAdminMemberships[0];
+ await updateUserMembership(organizationId, firstAdmin.userId, MembershipRole.owner);
+ } else if (currentUserIsOrganizationOwner) {
+ await deleteOrganization(organizationId);
}
}
diff --git a/apps/web/app/api/v1/users/route.ts b/apps/web/app/api/v1/users/route.ts
index e4b9ede0c3..1558477078 100644
--- a/apps/web/app/api/v1/users/route.ts
+++ b/apps/web/app/api/v1/users/route.ts
@@ -1,8 +1,8 @@
import { prisma } from "@formbricks/database";
import { sendInviteAcceptedEmail, sendVerificationEmail } from "@formbricks/email";
import {
- DEFAULT_TEAM_ID,
- DEFAULT_TEAM_ROLE,
+ DEFAULT_ORGANIZATION_ID,
+ DEFAULT_ORGANIZATION_ROLE,
EMAIL_AUTH_ENABLED,
EMAIL_VERIFICATION_DISABLED,
INVITE_DISABLED,
@@ -11,8 +11,8 @@ import {
import { deleteInvite } from "@formbricks/lib/invite/service";
import { verifyInviteToken } from "@formbricks/lib/jwt";
import { createMembership } from "@formbricks/lib/membership/service";
+import { createOrganization, getOrganization } from "@formbricks/lib/organization/service";
import { createProduct } from "@formbricks/lib/product/service";
-import { createTeam, getTeam } from "@formbricks/lib/team/service";
import { createUser, updateUser } from "@formbricks/lib/user/service";
export const POST = async (request: Request) => {
@@ -53,10 +53,10 @@ export const POST = async (request: Request) => {
// create the user
user = await createUser(user);
- // User is invited to team
+ // User is invited to organization
if (isInviteValid) {
- // assign user to existing team
- await createMembership(invite.teamId, user.id, {
+ // assign user to existing organization
+ await createMembership(invite.organizationId, user.id, {
accepted: true,
role: invite.role,
});
@@ -72,24 +72,27 @@ export const POST = async (request: Request) => {
}
// User signs up without invite
- // Default team assignment is enabled
- if (DEFAULT_TEAM_ID && DEFAULT_TEAM_ID.length > 0) {
- // check if team exists
- let team = await getTeam(DEFAULT_TEAM_ID);
- let isNewTeam = false;
- if (!team) {
- // create team with id from env
- team = await createTeam({ id: DEFAULT_TEAM_ID, name: user.name + "'s Team" });
- isNewTeam = true;
+ // Default organization assignment is enabled
+ if (DEFAULT_ORGANIZATION_ID && DEFAULT_ORGANIZATION_ID.length > 0) {
+ // check if organization exists
+ let organization = await getOrganization(DEFAULT_ORGANIZATION_ID);
+ let isNewOrganization = false;
+ if (!organization) {
+ // create organization with id from env
+ organization = await createOrganization({
+ id: DEFAULT_ORGANIZATION_ID,
+ name: user.name + "'s Organization",
+ });
+ isNewOrganization = true;
}
- const role = isNewTeam ? "owner" : DEFAULT_TEAM_ROLE || "admin";
- await createMembership(team.id, user.id, { role, accepted: true });
+ const role = isNewOrganization ? "owner" : DEFAULT_ORGANIZATION_ROLE || "admin";
+ await createMembership(organization.id, user.id, { role, accepted: true });
}
- // Without default team assignment
+ // Without default organization assignment
else {
- const team = await createTeam({ name: user.name + "'s Team" });
- await createMembership(team.id, user.id, { role: "owner", accepted: true });
- const product = await createProduct(team.id, { name: "My Product" });
+ const organization = await createOrganization({ name: user.name + "'s Organization" });
+ await createMembership(organization.id, user.id, { role: "owner", accepted: true });
+ const product = await createProduct(organization.id, { name: "My Product" });
const updatedNotificationSettings = {
...user.notificationSettings,
diff --git a/apps/web/app/lib/api/apiHelper.ts b/apps/web/app/lib/api/apiHelper.ts
index b481faf150..a4b0ea4747 100644
--- a/apps/web/app/lib/api/apiHelper.ts
+++ b/apps/web/app/lib/api/apiHelper.ts
@@ -49,12 +49,12 @@ export const hasApiEnvironmentAccess = async (apiKey, environmentId) => {
return false;
};
-export const hasTeamAccess = async (user, teamId) => {
+export const hasOrganizationAccess = async (user, organizationId) => {
const membership = await prisma.membership.findUnique({
where: {
- userId_teamId: {
+ userId_organizationId: {
userId: user.id,
- teamId: teamId,
+ organizationId: organizationId,
},
},
});
@@ -75,12 +75,12 @@ export const getSessionUser = async (req?: NextApiRequest, res?: NextApiResponse
if (session && "user" in session) return session.user;
};
-export const isOwner = async (user, teamId) => {
+export const isOwner = async (user, organizationId) => {
const membership = await prisma.membership.findUnique({
where: {
- userId_teamId: {
+ userId_organizationId: {
userId: user.id,
- teamId: teamId,
+ organizationId: organizationId,
},
},
});
@@ -90,12 +90,12 @@ export const isOwner = async (user, teamId) => {
return false;
};
-export const isAdminOrOwner = async (user, teamId) => {
+export const isAdminOrOwner = async (user, organizationId) => {
const membership = await prisma.membership.findUnique({
where: {
- userId_teamId: {
+ userId_organizationId: {
userId: user.id,
- teamId: teamId,
+ organizationId: organizationId,
},
},
});
diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx
index 019d9b0041..06761dcca6 100644
--- a/apps/web/app/page.tsx
+++ b/apps/web/app/page.tsx
@@ -5,7 +5,7 @@ import { redirect } from "next/navigation";
import { authOptions } from "@formbricks/lib/authOptions";
import { ONBOARDING_DISABLED } from "@formbricks/lib/constants";
import { getFirstEnvironmentByUserId } from "@formbricks/lib/environment/service";
-import { getTeamsByUserId } from "@formbricks/lib/team/service";
+import { getOrganizationsByUserId } from "@formbricks/lib/organization/service";
import { ClientLogout } from "@formbricks/ui/ClientLogout";
const Page = async () => {
@@ -19,10 +19,10 @@ const Page = async () => {
return ;
}
- const teams = await getTeamsByUserId(session.user.id);
- if (!teams || teams.length === 0) {
- console.error("Failed to get teams, redirecting to create-first-team");
- return redirect("/create-first-team");
+ const organizations = await getOrganizationsByUserId(session.user.id);
+ if (!organizations || organizations.length === 0) {
+ console.error("Failed to get organizations, redirecting to create-first-organization");
+ return redirect("/create-first-organization");
}
if (!ONBOARDING_DISABLED && !session.user.onboardingCompleted) {
diff --git a/apps/web/app/s/[surveyId]/page.tsx b/apps/web/app/s/[surveyId]/page.tsx
index ef6da6f4dc..f9f64b6f6b 100644
--- a/apps/web/app/s/[surveyId]/page.tsx
+++ b/apps/web/app/s/[surveyId]/page.tsx
@@ -9,11 +9,11 @@ import { notFound } from "next/navigation";
import { getMultiLanguagePermission } from "@formbricks/ee/lib/service";
import { IMPRINT_URL, IS_FORMBRICKS_CLOUD, PRIVACY_URL, WEBAPP_URL } from "@formbricks/lib/constants";
+import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
import { createPerson, getPersonByUserId } from "@formbricks/lib/person/service";
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
import { getResponseBySingleUseId, getResponseCountBySurveyId } from "@formbricks/lib/response/service";
import { getSurvey } from "@formbricks/lib/survey/service";
-import { getTeamByEnvironmentId } from "@formbricks/lib/team/service";
import { ZId } from "@formbricks/types/environment";
import { TResponse } from "@formbricks/types/responses";
import { MediaBackground } from "@formbricks/ui/MediaBackground";
@@ -57,11 +57,11 @@ const Page = async ({ params, searchParams }: LinkSurveyPageProps) => {
notFound();
}
- const team = await getTeamByEnvironmentId(survey?.environmentId);
- if (!team) {
- throw new Error("Team not found");
+ const organization = await getOrganizationByEnvironmentId(survey?.environmentId);
+ if (!organization) {
+ throw new Error("Organization not found");
}
- const isMultiLanguageAllowed = await getMultiLanguagePermission(team);
+ const isMultiLanguageAllowed = await getMultiLanguagePermission(organization);
if (survey && survey.status !== "inProgress") {
return (
diff --git a/apps/web/playwright/onboarding.spec.ts b/apps/web/playwright/onboarding.spec.ts
index 3b7c3dda92..a91cc1532a 100644
--- a/apps/web/playwright/onboarding.spec.ts
+++ b/apps/web/playwright/onboarding.spec.ts
@@ -1,9 +1,9 @@
import { expect, test } from "@playwright/test";
import { signUpAndLogin } from "./utils/helper";
-import { teams, users } from "./utils/mock";
+import { organizations, users } from "./utils/mock";
-const { productName } = teams.onboarding[0];
+const { productName } = organizations.onboarding[0];
test.describe("Onboarding Flow Test", async () => {
test("link survey", async ({ page }) => {
diff --git a/apps/web/playwright/team.spec.ts b/apps/web/playwright/organization.spec.ts
similarity index 88%
rename from apps/web/playwright/team.spec.ts
rename to apps/web/playwright/organization.spec.ts
index 70544d34d7..67210844e2 100644
--- a/apps/web/playwright/team.spec.ts
+++ b/apps/web/playwright/organization.spec.ts
@@ -3,12 +3,12 @@ import { expect, test } from "playwright/test";
import { finishOnboarding, login, signUpAndLogin, signupUsingInviteToken } from "./utils/helper";
import { invites, users } from "./utils/mock";
-test.describe("Invite, accept and remove team member", async () => {
+test.describe("Invite, accept and remove organization member", async () => {
test.describe.configure({ mode: "serial" });
- const { email, password, name } = users.team[0];
+ const { email, password, name } = users.organization[0];
let inviteLink: string;
- test("Invite team member", async ({ page }) => {
+ test("Invite organization member", async ({ page }) => {
await signUpAndLogin(page, name, email, password);
await finishOnboarding(page);
@@ -19,7 +19,7 @@ test.describe("Invite, accept and remove team member", async () => {
const dropdownInnerContentWrapper = page.locator("#userDropdownInnerContentWrapper");
await expect(dropdownInnerContentWrapper).toBeVisible();
- await page.getByRole("link", { name: "Team" }).click();
+ await page.getByRole("link", { name: "Organization" }).click();
await page.waitForURL(/\/environments\/[^/]+\/settings\/members/);
// Add member button
@@ -50,7 +50,7 @@ test.describe("Invite, accept and remove team member", async () => {
const dropdownInnerContentWrapper = page.locator("#userDropdownInnerContentWrapper");
await expect(dropdownInnerContentWrapper).toBeVisible();
- await page.getByRole("link", { name: "Team" }).click();
+ await page.getByRole("link", { name: "Organization" }).click();
await expect(page.locator("#membersInfoWrapper")).toBeVisible();
@@ -76,7 +76,7 @@ test.describe("Invite, accept and remove team member", async () => {
});
test("Accept invite", async ({ page }) => {
- const { email, name, password } = users.team[1];
+ const { email, name, password } = users.organization[1];
page.goto(inviteLink);
await page.waitForURL(/\/invite\?token=[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+/);
@@ -99,7 +99,7 @@ test.describe("Invite, accept and remove team member", async () => {
const dropdownInnerContentWrapper = page.locator("#userDropdownInnerContentWrapper");
await expect(dropdownInnerContentWrapper).toBeVisible();
- await page.getByRole("link", { name: "Team" }).click();
+ await page.getByRole("link", { name: "Organization" }).click();
await expect(page.locator("#membersInfoWrapper")).toBeVisible();
@@ -114,6 +114,6 @@ test.describe("Invite, accept and remove team member", async () => {
await expect(page.getByRole("button", { name: "Delete", exact: true })).toBeVisible();
await page.getByRole("button", { name: "Delete", exact: true }).click();
- await expect(page.getByText("team2@formbricks.com")).not.toBeVisible();
+ await expect(page.getByText("organization2@formbricks.com")).not.toBeVisible();
});
});
diff --git a/apps/web/playwright/utils/mock.ts b/apps/web/playwright/utils/mock.ts
index 2f2b457c73..1230ea949a 100644
--- a/apps/web/playwright/utils/mock.ts
+++ b/apps/web/playwright/utils/mock.ts
@@ -74,21 +74,21 @@ export const users = {
password: "XpP%X9UU3efj8vJa",
},
],
- team: [
+ organization: [
{
- name: "Team User 1",
- email: "team1@formbricks.com",
+ name: "Organization User 1",
+ email: "organization1@formbricks.com",
password: "Test#1234",
},
{
- name: "Team User 2",
- email: "team2@formbricks.com",
+ name: "Organization User 2",
+ email: "organization2@formbricks.com",
password: "Test#1234",
},
],
};
-export const teams = {
+export const organizations = {
onboarding: [
{
role: "Founder",
@@ -301,7 +301,7 @@ export const actions = {
export const invites = {
addMember: {
- name: "Team User 2",
- email: "team2@formbricks.com",
+ name: "Organization User 2",
+ email: "organization2@formbricks.com",
},
};
diff --git a/apps/web/public/sample-csv/formbricks-team-members-template.csv b/apps/web/public/sample-csv/formbricks-organization-members-template.csv
similarity index 100%
rename from apps/web/public/sample-csv/formbricks-team-members-template.csv
rename to apps/web/public/sample-csv/formbricks-organization-members-template.csv
diff --git a/docker-compose.yml b/docker-compose.yml
index dcb53c4d5e..661ca1bce0 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -5,14 +5,15 @@ x-webapp-url: &webapp_url http://localhost:3000
x-database-url: &database_url postgresql://postgres:postgres@postgres:5432/formbricks?schema=public
x-redis-url: &redis_url
+ # NextJS Auth
+ # @see: https://next-auth.js.org/configuration/options#nextauth_secret
+ # You can use: `openssl rand -hex 32` to generate one
-# NextJS Auth
-# @see: https://next-auth.js.org/configuration/options#nextauth_secret
-# You can use: `openssl rand -hex 32` to generate one
x-nextauth-secret: &nextauth_secret
# Set this to your public-facing URL, e.g., https://example.com
# You do not need the NEXTAUTH_URL environment variable in Vercel.
+
x-nextauth-url: &nextauth_url http://localhost:3000
# Encryption key
@@ -43,7 +44,7 @@ x-signup-disabled: &signup_disabled 0
# Email login. Disable the ability for users to login with email.
x-auth-disabled: &email_auth_disabled 0
-# Team Invite. Disable the ability for invited users to create an account.
+# Organization Invite. Disable the ability for invited users to create an account.
x-invite-disabled: &invite_disabled 0
# Set the below values to display privacy policy, imprint and terms of service links in the footer of signup & public pages.
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index 02e23b4269..55fd147919 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -154,11 +154,11 @@ x-environment: &environment
############################################# OPTIONAL (OTHER) #############################################
- # Set the below to automatically assign new users to a specific team and role within that team
- # Insert an existing team id or generate a valid CUID for a new one at https://www.getuniqueid.com/cuid (e.g. cjld2cjxh0000qzrmn831i7rn)
+ # Set the below to automatically assign new users to a specific organization and role within that organization
+ # Insert an existing organization id or generate a valid CUID for a new one at https://www.getuniqueid.com/cuid (e.g. cjld2cjxh0000qzrmn831i7rn)
# (Role Management is an Enterprise feature)
- # DEFAULT_TEAM_ID:
- # DEFAULT_TEAM_ROLE: admin
+ # DEFAULT_ORGANIZATION_ID:
+ # DEFAULT_ORGANIZATION_ROLE: admin
services:
postgres:
diff --git a/kamal/deploy.yml b/kamal/deploy.yml
index 77265e9486..2f31f97060 100644
--- a/kamal/deploy.yml
+++ b/kamal/deploy.yml
@@ -76,7 +76,7 @@ env:
- GOOGLE_SHEETS_REDIRECT_URL
- AIRTABLE_CLIENT_ID
- ENTERPRISE_LICENSE_KEY
- - DEFAULT_TEAM_ID
+ - DEFAULT_ORGANIZATION_ID
- ONBOARDING_DISABLED
- CUSTOMER_IO_API_KEY
- CUSTOMER_IO_SITE_ID
diff --git a/packages/database/jsonTypes.ts b/packages/database/jsonTypes.ts
index 886c15b7af..727cf28b0b 100644
--- a/packages/database/jsonTypes.ts
+++ b/packages/database/jsonTypes.ts
@@ -1,5 +1,6 @@
import { TActionClassNoCodeConfig } from "@formbricks/types/actionClasses";
import { TIntegrationConfig } from "@formbricks/types/integration";
+import { TOrganizationBilling } from "@formbricks/types/organizations";
import { TProductStyling } from "@formbricks/types/product";
import { TResponseData, TResponseMeta, TResponsePersonAttributes } from "@formbricks/types/responses";
import { TBaseFilters } from "@formbricks/types/segment";
@@ -14,7 +15,6 @@ import {
TSurveyVerifyEmail,
TSurveyWelcomeCard,
} from "@formbricks/types/surveys";
-import { TTeamBilling } from "@formbricks/types/teams";
import { TUserNotificationSettings } from "@formbricks/types/user";
declare global {
@@ -34,7 +34,7 @@ declare global {
export type SurveyClosedMessage = TSurveyClosedMessage;
export type SurveySingleUse = TSurveySingleUse;
export type SurveyVerifyEmail = TSurveyVerifyEmail;
- export type TeamBilling = TTeamBilling;
+ export type OrganizationBilling = TOrganizationBilling;
export type UserNotificationSettings = TUserNotificationSettings;
export type SegmentFilter = TBaseFilters;
export type Styling = TProductStyling;
diff --git a/packages/database/migrations/20240516122752_rename_teams_to_organizations/migration.sql b/packages/database/migrations/20240516122752_rename_teams_to_organizations/migration.sql
new file mode 100644
index 0000000000..5e663d94a1
--- /dev/null
+++ b/packages/database/migrations/20240516122752_rename_teams_to_organizations/migration.sql
@@ -0,0 +1,28 @@
+-- Rename table from "Team" to "Organization"
+ALTER TABLE "Team" RENAME TO "Organization";
+ALTER TABLE "Organization" RENAME CONSTRAINT "Team_pkey" TO "Organization_pkey";
+
+-- Rename column in the "Product" table
+ALTER TABLE "Product" RENAME COLUMN "teamId" TO "organizationId";
+
+-- Rename column in the "Invite" table
+ALTER TABLE "Invite" RENAME COLUMN "teamId" TO "organizationId";
+
+-- Rename column in the "Membership" table
+ALTER TABLE "Membership" RENAME COLUMN "teamId" TO "organizationId";
+
+-- Rename foreign key constraints
+ALTER TABLE "Invite" RENAME CONSTRAINT "Invite_teamId_fkey" TO "Invite_organizationId_fkey";
+ALTER TABLE "Membership" RENAME CONSTRAINT "Membership_teamId_fkey" TO "Membership_organizationId_fkey";
+ALTER TABLE "Product" RENAME CONSTRAINT "Product_teamId_fkey" TO "Product_organizationId_fkey";
+
+-- Rename indexes
+ALTER INDEX "Invite_email_teamId_idx" RENAME TO "Invite_email_organizationId_idx";
+ALTER INDEX "Invite_teamId_idx" RENAME TO "Invite_organizationId_idx";
+ALTER INDEX "Membership_teamId_idx" RENAME TO "Membership_organizationId_idx";
+ALTER INDEX "Product_teamId_idx" RENAME TO "Product_organizationId_idx";
+ALTER INDEX "Product_teamId_name_key" RENAME TO "Product_organizationId_name_key";
+
+-- Drop and recreate primary key on Membership table
+ALTER TABLE "Membership" DROP CONSTRAINT "Membership_pkey";
+ALTER TABLE "Membership" ADD CONSTRAINT "Membership_pkey" PRIMARY KEY ("userId", "organizationId");
diff --git a/packages/database/schema.prisma b/packages/database/schema.prisma
index 82ab12a623..0f405016b4 100644
--- a/packages/database/schema.prisma
+++ b/packages/database/schema.prisma
@@ -422,8 +422,8 @@ model Product {
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @updatedAt @map(name: "updated_at")
name String
- team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
- teamId String
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
+ organizationId String
environments Environment[]
brandColor String?
highlightBorderColor String?
@@ -441,19 +441,19 @@ model Product {
/// [Logo]
logo Json?
- @@unique([teamId, name])
- @@index([teamId])
+ @@unique([organizationId, name])
+ @@index([organizationId])
}
-model Team {
+model Organization {
id String @id @default(cuid())
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @updatedAt @map(name: "updated_at")
name String
memberships Membership[]
products Product[]
- /// @zod.custom(imports.ZTeamBilling)
- /// [TeamBilling]
+ /// @zod.custom(imports.ZOrganizationBilling)
+ /// [OrganizationBilling]
billing Json @default("{\"stripeCustomerId\": null, \"features\": {\"inAppSurvey\": {\"status\": \"inactive\", \"unlimited\": false}, \"linkSurvey\": {\"status\": \"inactive\", \"unlimited\": false}, \"userTargeting\": {\"status\": \"inactive\", \"unlimited\": false}}}")
invites Invite[]
}
@@ -467,35 +467,35 @@ enum MembershipRole {
}
model Membership {
- team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
- teamId String
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- userId String
- accepted Boolean @default(false)
- role MembershipRole
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
+ organizationId String
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+ userId String
+ accepted Boolean @default(false)
+ role MembershipRole
- @@id([userId, teamId])
+ @@id([userId, organizationId])
@@index([userId])
- @@index([teamId])
+ @@index([organizationId])
}
model Invite {
- id String @id @default(uuid())
- email String
- name String?
- team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
- teamId String
- creator User @relation("inviteCreatedBy", fields: [creatorId], references: [id])
- creatorId String
- acceptor User? @relation("inviteAcceptedBy", fields: [acceptorId], references: [id], onDelete: Cascade)
- acceptorId String?
- accepted Boolean @default(false)
- createdAt DateTime @default(now())
- expiresAt DateTime
- role MembershipRole @default(admin)
+ id String @id @default(uuid())
+ email String
+ name String?
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
+ organizationId String
+ creator User @relation("inviteCreatedBy", fields: [creatorId], references: [id])
+ creatorId String
+ acceptor User? @relation("inviteAcceptedBy", fields: [acceptorId], references: [id], onDelete: Cascade)
+ acceptorId String?
+ accepted Boolean @default(false)
+ createdAt DateTime @default(now())
+ expiresAt DateTime
+ role MembershipRole @default(admin)
- @@index([email, teamId])
- @@index([teamId])
+ @@index([email, organizationId])
+ @@index([organizationId])
}
model ApiKey {
diff --git a/packages/database/zod-utils.ts b/packages/database/zod-utils.ts
index 14432218a8..2225477a1d 100644
--- a/packages/database/zod-utils.ts
+++ b/packages/database/zod-utils.ts
@@ -25,5 +25,5 @@ export {
} from "@formbricks/types/surveys";
export { ZSegmentFilters } from "@formbricks/types/segment";
-export { ZTeamBilling } from "@formbricks/types/teams";
+export { ZOrganizationBilling } from "@formbricks/types/organizations";
export { ZUserNotificationSettings } from "@formbricks/types/user";
diff --git a/packages/ee/RoleManagement/components/EditMembershipRole.tsx b/packages/ee/RoleManagement/components/EditMembershipRole.tsx
index cca09136f4..ab0bfb5d84 100644
--- a/packages/ee/RoleManagement/components/EditMembershipRole.tsx
+++ b/packages/ee/RoleManagement/components/EditMembershipRole.tsx
@@ -23,7 +23,7 @@ import { TransferOwnershipModal } from "./TransferOwnershipModal";
interface Role {
isAdminOrOwner: boolean;
memberRole: TMembershipRole;
- teamId: string;
+ organizationId: string;
memberId?: string;
memberName: string;
userId: string;
@@ -35,7 +35,7 @@ interface Role {
export const EditMembershipRole = ({
isAdminOrOwner,
memberRole,
- teamId,
+ organizationId,
memberId,
memberName,
userId,
@@ -55,11 +55,11 @@ export const EditMembershipRole = ({
try {
if (memberAccepted && memberId) {
- await updateMembershipAction(memberId, teamId, { role });
+ await updateMembershipAction(memberId, organizationId, { role });
}
if (inviteId) {
- await updateInviteAction(inviteId, teamId, { role });
+ await updateInviteAction(inviteId, organizationId, { role });
}
} catch (error) {
toast.error("Something went wrong");
@@ -73,7 +73,7 @@ export const EditMembershipRole = ({
setLoading(true);
try {
if (memberId) {
- await transferOwnershipAction(teamId, memberId);
+ await transferOwnershipAction(organizationId, memberId);
}
setLoading(false);
diff --git a/packages/ee/RoleManagement/components/TransferOwnershipModal.tsx b/packages/ee/RoleManagement/components/TransferOwnershipModal.tsx
index a5bb073c6e..fcd5559bfa 100644
--- a/packages/ee/RoleManagement/components/TransferOwnershipModal.tsx
+++ b/packages/ee/RoleManagement/components/TransferOwnershipModal.tsx
@@ -39,10 +39,10 @@ export const TransferOwnershipModal = ({
- There can only be one owner of each team. If you transfer your ownership to {memberName},
- you will lose all of your ownership rights.
+ There can only be one owner of each organization. If you transfer your ownership to{" "}
+ {memberName}, you will lose all of your ownership rights.
-
When you transfer the ownership, you will remain an Admin of the team.
+
When you transfer the ownership, you will remain an Admin of the organization.
-
Create team
+
Create organization
- Create a new team to handle a different set of products.
+ Create a new organization to handle a different set of products.