import { eq } from "drizzle-orm"; import { db } from "../../db"; import { projects, uploads } from "../../db/schema"; import { createEmptyProject } from "../../helper/projects/createProject"; import { createBucket } from "../../helper/upload/createBucket"; import { removeBucket } from "../../helper/upload/removeBucket"; export const getAllProjects = async (userId: string, token: string) => { try { // Fetch all projects for the given user const allProjects = await db .select({ id: projects.id, name: projects.name, description: projects.description, preview_url: projects.preview_url, object: projects.object, }) .from(projects) .where(eq(projects.userId, userId)); // Identify projects where 'object' is empty or 'object.objects' is empty const projectsToDelete = allProjects.filter( (proj) => (proj.object && typeof proj.object === "object" && Object.keys(proj.object).length === 0) || (proj.object?.objects && Array.isArray(proj.object.objects) && proj.object.objects.length === 0) ); // Delete projects with empty 'object' or empty 'object.objects' await Promise.all( projectsToDelete.map(async (proj) => { // Step 1: Delete associated uploads first await db.delete(uploads).where(eq(uploads.projectId, proj.id)); // Step 2: Delete the project itself await db.delete(projects).where(eq(projects.id, proj.id)); // Step 3: Delete the associated bucket await removeBucket(proj.id); }) ); // Get remaining projects const remainingProjects = allProjects.filter( (proj) => !( (proj.object && typeof proj.object === "object" && Object.keys(proj.object).length === 0) || (proj.object?.objects && Array.isArray(proj.object.objects) && proj.object.objects.length === 0) ) ); if (remainingProjects.length === 0) { return { status: 404, message: "No projects found", token }; } return { status: 200, message: "Projects fetched successfully", data: remainingProjects, token, }; } catch (error: any) { console.log(error.message); return { status: 500, message: "An error occurred while fetching projects", token, }; } }; export const getEachProjects = async (id: string, token: string) => { try { const project = await db .select({ id: projects.id, name: projects.name, description: projects.description, preview_url: projects.preview_url, object: projects.object, }) .from(projects) .where(eq(projects.id, id)) .limit(1); if (project.length === 0) { return { status: 404, message: "Project not found", token }; } return { status: 200, message: "Project fetched successfully", data: project[0], token, }; } catch (error: any) { console.log(error.message); return { status: 500, message: "An error occurred while fetching projects", token, }; } }; export const createProject = async (userId: string, token: string) => { try { const { id } = await createEmptyProject(userId); const bucket = await createBucket(id); return { status: 200, message: "New project created successfully", data: { id, bucketName: bucket }, token, }; } catch (error: any) { console.log(error.message); return { status: 500, message: "An error occurred while creating projects", token, }; } }; export const updateProject = async ( id: string, body: any, token: string, user_id: string ) => { try { // 1. Validate if project exists const existingProject = await db .select() .from(projects) .where(eq(projects.id, id)); if (existingProject.length === 0) { return { status: 404, message: "Project not found", token }; } const { object, name, description, preview_url } = body; // The preview_url will come from client-side as well, where before updating the project a project capture will be taken and uploaded to the bucket. than the url will be sent to the server.And rest of them are normal process const updatedProject = await db .update(projects) .set({ object, name, description, preview_url, userId: user_id, }) .where(eq(projects.id, id)) .returning({ id: projects.id, object: projects.object, name: projects.name, description: projects.description, preview_url: projects.preview_url, }); if (updatedProject.length === 0) { return { status: 500, message: "Failed to update the project", token }; } return { status: 200, message: "Project updated successfully", data: updatedProject[0], token, }; } catch (error: any) { console.log("Error updating project:", error.message || error.toString()); return { status: 500, message: "An error occurred while updating the project", token, }; } }; export const deleteProject = async (id: string, token: string) => { try { const deletedUploads = await db .delete(uploads) .where(eq(uploads.projectId, id)) .returning({ id: uploads.id }); if (deletedUploads.length >= 0) { // Step 4: Delete the project const deletedProject = await db .delete(projects) .where(eq(projects.id, id)) .returning({ id: projects.id }); if (deletedProject.length === 0) { return { status: 404, message: "Project not found", token }; } // Step 5: Delete the associated bucket const bucketDeletionResult = await removeBucket(id); if (bucketDeletionResult.status !== 200) { return { status: bucketDeletionResult.status, message: `Error deleting bucket: ${bucketDeletionResult.message}`, token, }; } return { status: 200, message: "Project and associated bucket deleted successfully", token, }; } } catch (error: any) { console.log("Error in deleteProject:", error.message || error.toString()); return { status: 500, message: "An error occurred while deleting the project", token, }; } };