The only comment here that I don’t strongly-agree with, is the one about a database-column being not null default ''. Although it is a bit of a pain to deal with the difference in code, there is nonetheless an important difference in meaning. The absence of any value is not the same as an empty-string value. The latter, to me, implies that “the value is known, and it is known to be an empty-string.” Queries that might be run by clients entirely separate from this application, e.g. SELECT COUNT(colname) issued by some report-whatnot, would be thrown-off considerably by empty-string values, being lured into counting something that more-properly “isn’t there.”
Mind you, it is not that I categorically-disagree with this practice; merely that I often-do.
Beyond that, a series of very excellent points; upvoted.