Lawhive Framework
FrameworkPrisma

Prisma Extensions

Soft delete and audit trail extensions for Prisma

The framework provides two Prisma Client extensions that work seamlessly together:

  • Soft Delete - Convert deletes to updates with deletedAt timestamps
  • Audit Trail - Automatically log all mutations with before/after state

Integrated Usage

The audit extension has built-in soft delete support via the softDelete config option. This is the recommended way to use both together:

import { PrismaClient } from "@prisma/client"
import {
  createAuditedPrismaClient,
  getAuditContext,
} from "@lawhive/framework"

const basePrisma = new PrismaClient()

const EXCLUDED_MODELS = ["AuditLog", "Outbox", "Event"]

const prisma = createAuditedPrismaClient(basePrisma, {
  getContext: getAuditContext,
  excludeModels: EXCLUDED_MODELS,
  writer: async (record, tx) => {
    await tx.auditLog.create({ data: { ... } })
  },
  softDelete: {
    excludeModels: EXCLUDED_MODELS,
  },
})

How They Work Together

When you call prisma.task.delete():

  1. The extension intercepts the delete and converts to update({ deletedAt: new Date() })
  2. The audit system detects this is a soft-delete
  3. The audit log records it as a delete operation (not update)

Standalone Soft Delete

If you only need soft delete without audit, use createSoftDeleteClient directly:

import { createSoftDeleteClient } from "@lawhive/framework"

const prisma = createSoftDeleteClient(basePrisma, {
  excludeModels: ["AuditLog", "Outbox"],
})

Excluded Models

Both soft delete and audit support excludeModels to skip certain tables:

const EXCLUDED_MODELS = ["AuditLog", "Outbox", "Session"]

const prisma = createAuditedPrismaClient(basePrisma, {
  excludeModels: EXCLUDED_MODELS,
  softDelete: { excludeModels: EXCLUDED_MODELS },
  // ...
})

Exclude models that:

  • Store audit logs themselves (avoid recursion)
  • Don't need soft delete (system tables)
  • Have their own lifecycle management

Next Steps