Feature Request
Until we have full Pydantic-compliant models (#98), we rely on custom deserialization in the routes, e.g.:
ballots = [PlaintextBallot.from_json_object(ballot) for ballot in request.ballots]
If this deserialization fails, however, it manifests as an opaque 500 error to the client. We should capture deserialization errors and send a 400 with as much information as possible.