Deleting User Account and All Related Data
I'm implementing a way for users to delete all their related data using Next.js 14 with App Router. This is my server action to handle data deletion after user confirmation:
This is the frontend function that gets called when confirm is clicked:
'use server';
import { db } from '../lib/db';
import { S3Client, DeleteObjectCommand } from '@aws-sdk/client-s3';
const s3 = new S3Client({
region: AWS_REGION,
credentials: {
accessKeyId: AWS_KEY,
secretAccessKey: AWS_SECRET,
},
});
export async function deleteUserAccount(userId: string) {
try {
const resumes = await db.resume.findMany({
where: { userId },
include: {
personalInfo: true,
},
});
for (const resume of resumes) {
if (resume.personalInfo?.imagePath) {
const imageName = resume.personalInfo.imagePath.split('/').pop();
if (imageName) {
await s3.send(
new DeleteObjectCommand({
Bucket: process.env.AWS_BUCKET_NAME,
Key: imageName,
}),
);
}
}
}
await db.$transaction([
db.personalInfo.deleteMany({ where: { resume: { userId } } }),
db.workExperience.deleteMany({ where: { resume: { userId } } }),
...
db.resume.deleteMany({ where: { userId } }),
db.coverletter.deleteMany({ where: { userId } }),
db.account.deleteMany({ where: { userId } }),
db.session.deleteMany({ where: { userId } }),
db.user.delete({ where: { id: userId } }),
]);
return { success: true };
} catch (error) {
return { success: false, error: 'Failed to delete account' };
}
}'use server';
import { db } from '../lib/db';
import { S3Client, DeleteObjectCommand } from '@aws-sdk/client-s3';
const s3 = new S3Client({
region: AWS_REGION,
credentials: {
accessKeyId: AWS_KEY,
secretAccessKey: AWS_SECRET,
},
});
export async function deleteUserAccount(userId: string) {
try {
const resumes = await db.resume.findMany({
where: { userId },
include: {
personalInfo: true,
},
});
for (const resume of resumes) {
if (resume.personalInfo?.imagePath) {
const imageName = resume.personalInfo.imagePath.split('/').pop();
if (imageName) {
await s3.send(
new DeleteObjectCommand({
Bucket: process.env.AWS_BUCKET_NAME,
Key: imageName,
}),
);
}
}
}
await db.$transaction([
db.personalInfo.deleteMany({ where: { resume: { userId } } }),
db.workExperience.deleteMany({ where: { resume: { userId } } }),
...
db.resume.deleteMany({ where: { userId } }),
db.coverletter.deleteMany({ where: { userId } }),
db.account.deleteMany({ where: { userId } }),
db.session.deleteMany({ where: { userId } }),
db.user.delete({ where: { id: userId } }),
]);
return { success: true };
} catch (error) {
return { success: false, error: 'Failed to delete account' };
}
}This is the frontend function that gets called when confirm is clicked:
const handleDeleteAccount = async () => {
setIsDeleting(true);
const result = await deleteUserAccount(user.id);
setIsDeleting(false);
if (result.success) {
await signOut({ redirect: false });
router.push('/');
} else {
console.error(result.error);
}
}; const handleDeleteAccount = async () => {
setIsDeleting(true);
const result = await deleteUserAccount(user.id);
setIsDeleting(false);
if (result.success) {
await signOut({ redirect: false });
router.push('/');
} else {
console.error(result.error);
}
};