Prisma Soft Delete Middleware

1.3.1 · maintenance · verified Wed Apr 22

prisma-soft-delete-middleware is a utility library for Prisma that provides an efficient way to implement soft deletion for database records using Prisma's middleware system. The current stable version is `1.3.1`. It is actively maintained with a history of regular updates, including recent bug fixes and feature enhancements, though its release cadence may slow as the community shifts towards Prisma Extensions. This library's key differentiator is its ability to automatically handle cascading soft deletes across related models and to filter out soft-deleted records from various Prisma queries, including `findFirst`, `findMany`, `findUnique`, and operations involving `include` or `select`. It achieves this by intelligently modifying query arguments before they reach the database, leveraging `prisma-nested-middleware` for complex nested scenarios. While functional and maintained, Prisma's middleware system is deprecated in favor of Prisma Extensions, and users are encouraged to migrate to `prisma-extension-soft-delete` for future-proof applications.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates how to set up the soft delete middleware with a PrismaClient, create and soft-delete a record, and then query for it both with and without explicitly including soft-deleted records.

import { PrismaClient } from '@prisma/client';
import { createSoftDeleteMiddleware } from 'prisma-soft-delete-middleware';

// Example Prisma Schema:
// model User {
//   id        String    @id @default(uuid())
//   email     String    @unique
//   name      String?
//   deleted   Boolean   @default(false)
//   posts     Post[]
// }
// model Post {
//   id        String    @id @default(uuid())
//   title     String
//   content   String?
//   published Boolean   @default(false)
//   authorId  String
//   author    User      @relation(fields: [authorId], references: [id])
//   deleted   Boolean   @default(false)
// }

const prisma = new PrismaClient();

prisma.$use(createSoftDeleteMiddleware({
  models: {
    User: true, // Enable soft delete for User model
    Post: { field: 'deleted', deleteValue: true, includeSoftDeleted: false },
  },
}));

async function main() {
  // Create a user and a post
  const user = await prisma.user.create({
    data: { email: 'test@example.com', name: 'Test User' },
  });
  console.log('Created user:', user);

  const post = await prisma.post.create({
    data: { title: 'First Post', authorId: user.id },
  });
  console.log('Created post:', post);

  // Soft delete the user (and cascade to post if configured)
  await prisma.user.delete({ where: { id: user.id } });
  console.log(`Soft deleted user with ID: ${user.id}`);

  // Attempt to find the user (should not be found by default)
  const foundUser = await prisma.user.findUnique({ where: { id: user.id } });
  console.log('Found user after soft delete (default):', foundUser);

  // Find the user, explicitly including soft-deleted records
  const foundSoftDeletedUser = await prisma.user.findUnique({ 
    where: { id: user.id },
    // This is a special flag added by the middleware config for the model
    includeSoftDeleted: true 
  });
  console.log('Found soft-deleted user (explicitly):', foundSoftDeletedUser);

  // Find all posts (soft-deleted post should not be found by default)
  const allPosts = await prisma.post.findMany();
  console.log('All posts (default):', allPosts);

  // Find all posts, including soft-deleted ones (if 'Post' model was configured with includeSoftDeleted in middleware)
  const allPostsIncludingDeleted = await prisma.post.findMany({ includeSoftDeleted: true });
  console.log('All posts (including deleted):', allPostsIncludingDeleted);

} 

main().catch(e => {
  console.error(e);
  process.exit(1);
}).finally(async () => {
  await prisma.$disconnect();
});

view raw JSON →