Is it save to assume that this is a valid email address here? Otherwise we'll crash below.
Maybe just do the ?? null if it's not guaranteed that email is valid.
Same as above.
This reverse migration will not restore the data column. Perhaps add a FIXME so we have a chance to spot it before executing it.
We validate the email in the controller. And as we don't want invalid emails in here, I think an error is what we actually want to happen on an invalid email. So, I would not change this.
I guess we can add the reverse operation to what we do in up(). I'll add this. Just truncating the table (making existing codes invalid) wouldn't be a big deal too, imo.