Files
portabase/src/components/wrappers/dashboard/organization/organization.action.ts
T
2025-07-28 16:53:21 +02:00

261 lines
9.6 KiB
TypeScript

"use server";
import {userAction} from "@/safe-actions";
import {OrganizationSchema} from "@/components/wrappers/dashboard/organization/organization.schema";
import {ServerActionResult} from "@/types/action-type";
import {z} from "zod";
import {
OrganizationFormSchema
} from "@/components/wrappers/dashboard/organization/organization-form/organization-form.schema";
import {db} from "@/db";
import {and, eq, inArray} from "drizzle-orm";
import {auth, checkSlugOrganization, createOrganization, deleteOrganization} from "@/lib/auth/auth";
import {slugify} from "@/utils/slugify";
import {Organization} from "@/db/schema/02_organization";
import * as drizzleDb from "@/db";
import {headers} from "next/headers";
export const createOrganizationAction = userAction.schema(OrganizationSchema).action(async ({parsedInput}): Promise<ServerActionResult<Organization>> => {
try {
const slug = slugify(parsedInput.name);
if (!await checkSlugOrganization(slug)) {
return {
success: false,
actionError: {
message: "Slug is already taken",
status: 500,
messageParams: {message: "Error creating the organization"},
},
};
}
let createdOrganization: Organization;
try {
createdOrganization = await createOrganization(parsedInput.name, slug) as unknown as Organization;
} catch (authError: any) {
console.error("Auth deletion failed:", authError);
return {
success: false,
actionError: {
message: authError.message || "Authentication service error.",
status: authError.status || 500,
cause: "auth_error",
messageParams: {message: authError.message},
},
};
}
return {
success: true,
value: createdOrganization,
actionSuccess: {
message: "Organization has been successfully created.",
messageParams: {organizationId: createdOrganization!.id},
},
};
} catch (error) {
console.error("Error creating organization:", error);
return {
success: false,
actionError: {
message: "Failed to create organization.",
status: 500,
messageParams: {message: "Error creating the organization"},
},
};
}
});
export const updateOrganizationAction = userAction
.schema(
z.object({
data: OrganizationFormSchema,
organizationId: z.string(),
})
)
.action(async ({parsedInput, ctx}): Promise<ServerActionResult<Organization>> => {
try {
const newUserList = parsedInput.data.users;
console.log(parsedInput);
const organization = await db.query.organization.findFirst({
where: eq(drizzleDb.schemas.organization.id, parsedInput.organizationId),
with: {
members: true,
}
});
if (!organization) {
return {
success: false,
actionError: {
message: "Organization not found.",
status: 404,
cause: "not_found",
},
};
}
const existingItemIds = organization.members
.filter((member) => member.userId !== ctx.user.id)
.map((member) => member.userId);
const usersToAdd = newUserList.filter((id) => !existingItemIds.includes(id));
const usersToRemove = existingItemIds.filter((id) => !newUserList.includes(id));
if (usersToAdd.length > 0) {
for (const userToAdd of usersToAdd) {
await auth.api.addMember({
body: {
userId: userToAdd,
role: "member",
organizationId: organization.id,
},
});
}
//
// await db
// .insert(drizzleDb.schemas.member)
// .values(
// usersToAdd.map((userId) => ({
// userId,
// organizationId: organization.id,
// role: "member",
// }))
// )
// .execute();
}
if (usersToRemove.length > 0) {
await db.delete(drizzleDb.schemas.member).where(and(inArray(drizzleDb.schemas.member.userId, usersToRemove), eq(drizzleDb.schemas.member.organizationId, organization.id))).execute();
// TODO : Do not delete, go permission error with better auth
// for (const userToRemove of usersToRemove) {
//
// const memberToRemove = await db.query.member.findFirst({
// where: and(eq(drizzleDb.schemas.member.userId, userToRemove), eq(drizzleDb.schemas.member.organizationId, organization.id)),
// with: {
// user: true
// }
// })
// console.log(memberToRemove)
//
// if (memberToRemove) {
// console.log("ici")
// await auth.api.removeMember({
// body: {
// memberIdOrEmail: memberToRemove.user.email,
// organizationId: organization.id,
// },
// headers: await headers()
// });
// }
//
// }
}
// const updatedOrganization = await auth.api.updateOrganization({
// body: {
// data: {
// name: parsedInput.data.name,
// slug: parsedInput.data.slug,
// },
// organizationId: organization.id,
// },
// headers: await headers(),
// });
const updatedOrganization = await db
.update(drizzleDb.schemas.organization)
.set({
name: parsedInput.data.name,
slug: parsedInput.data.slug,
})
.where(eq(drizzleDb.schemas.organization.id, parsedInput.organizationId))
.returning()
.execute();
return {
success: true,
value: updatedOrganization as unknown as Organization,
actionSuccess: {
message: "Organization has been successfully updated.",
messageParams: {organizationId: organization.id},
},
};
} catch (error) {
console.error("Error updating organization:", error);
return {
success: false,
actionError: {
message: "Failed to update organization.",
status: 500,
cause: "server_error",
messageParams: {message: "Error updating the organization"},
},
};
}
});
export const deleteOrganizationAction = userAction.schema(z.string()).action(
async ({parsedInput, ctx}): Promise<ServerActionResult<Organization>> => {
try {
const org = await db.query.organization.findFirst({
where: eq(drizzleDb.schemas.organization.slug, parsedInput),
});
if (!org) {
return {
success: false,
actionError: {
message: "Organization not found.",
status: 404,
cause: "not_found",
},
};
}
let deletedOrganization: Organization;
try {
deletedOrganization = await deleteOrganization(org.id) as Organization;
} catch (authError: any) {
console.error("Auth deletion failed:", authError);
return {
success: false,
actionError: {
message: authError.message || "Authentication service error.",
status: authError.status || 500,
cause: "auth_error",
messageParams: {message: authError.message},
},
};
}
return {
success: true,
value: deletedOrganization,
actionSuccess: {
message: "Organization has been successfully deleted.",
messageParams: {organizationId: deletedOrganization.id},
},
};
} catch (error) {
console.error("Unexpected error in deleteOrganizationAction:", error);
return {
success: false,
actionError: {
message: "Failed to delete organization due to a server error.",
status: 500,
cause: "server_error",
messageParams: {message: "Internal server error while deleting the organization"},
},
};
}
}
);