Delayed Delete Example
In this example we implement a delayed delete functionality with un-delete option. This way we get rid of user data for real, so we are GDPR compliant and don't risk leaking something that user thought he has deleted. While also giving him 1 day to undo his action in case he has deleted something by accident.
Architectural overview
We will use a deleted
flag on our entity to hide if from UI. We need to filter them out in all the places we fetch entities. Real deletion of item will be pushed to the deleteNote
queue and processed in 24 hours. If in the meantime user decides to undo his action we remove deleted
flag and remove item from queue by key.
Code example
import lq from '@dayone-labs/lambda-queue-express'
import { hoursToMilliseconds } from 'date-fns'
import './models'
const deleteNoteQueue = lq.queue(
'/deleteNote',
async (event: { noteId: NoteId }) => {
await noteRepository.delete(event.noteId)
},
//Delete for real after 24 hours
{ delay: hoursToMilliseconds(24) }
)
const deleteNote = async (noteId: NoteId) => {
const note = await noteRepository.fetch(noteId)
//Mark as deleted, so it won't show up in UI
note.deleted = true
noteRepository.save(note)
await deleteNoteQueue.push({ noteId }, { key: noteId })
}
const undeleteNote = async (noteId: NoteId) => {
const note = await noteRepository.fetch(noteId)
//Remove from queue, so it's not deleted
await deleteNoteQueue.deleteByKey(noteId)
//Remove deleted flag, so it will show up in UI again
note.deleted = false
noteRepository.save(note)
}
//Queue is an Express router, just mount it with app.use(queue)
export default {
route: deleteNoteQueue,
deleteNote,
undeleteNote,
}
Remarks
TIP
Another common pattern to handle deleted items is to, instead of using deleted
flag, move items to deleted_notes
table or collection and move it back when un-deleted. This has few advantages over the flag:
- Real data is not polluted with deleted items, improving query performance.
- There's no need to filter out deleted items in application logic.
- You can skip deleted items from long term backups.
- A different storage strategy can be used for deleted and live items (table partitions, cheaper storage, etc.)