Soft delete dùng deleted_at TIMESTAMPTZ thay vì xóa thật — mọi query phải filter WHERE deleted_at IS NULL; dùng partial unique index để cho phép re-register email; hard delete vẫn cần cho GDPR erasure.
- Soft delete: thêm
deleted_at TIMESTAMPTZ(preferred hơnis_deleted BOOLEANvì biết thêm thời điểm xóa), không xóa record. - Implementation: mọi query phải thêm
WHERE deleted_at IS NULL— dùng partial index để tối ưu:CREATE INDEX idx_users_active ON users(email) WHERE deleted_at IS NULL, query chỉ scan active records. - Prisma middleware tự động add filter:
prisma.$use(async (params, next) => { if (params.action === 'findMany') params.args.where = { ...params.args.where, deletedAt: null }; return next(params); }). - Ưu điểm: undelete/recovery, audit trail (ai xóa khi nào), foreign key references không bị broken, GDPR right-to-erasure cần thêm bước anonymize.
- Nhược điểm: tất cả queries phải nhớ filter
deleted_at IS NULL— dễ quên gây data leak; bảng phình to theo thời gian; UNIQUE constraints vẫn enforce trên deleted records —email UNIQUEkhông cho phép re-register sau khi soft-delete → dùng partial unique indexWHERE deleted_at IS NULL. - Hard delete vẫn cần cho: GDPR erasure requests, sensitive PII, log/audit records cũ sau retention period.