The main benefit to the existentialized approach, IMO, is when the actions are entirely derived from type class operations. Sandy Maguire gave a good talk on the approach at Lambdaconf [3]. Since much of the behavior here is ad hoc, then I think you'll get less utility out of the class.
We have a similar sort of framework on our projects at work, but using Amazon SQS messages instead of a database. The function has a signature like:
pollSqsFor :: FromJSON a => SqsQueue -> (a -> App b) -> App ()
This lets us write `pollSqsFor ImportThing (thingImporter :: ThingRequest -> App ())` for the workers that end up processing it, with the polling function handling stuff like delay time, error handling, keeping the message invisible, deleting it if successful, etc. This sort of thing would be easy to port to using a database, the only difference being loading only matching rows from the database for the given type.