delete_generations_by_profile (and the version sweep under it) committed on
their own, so a failure between the generation sweep and the profile row
left the profile listed with its history already gone. Both helpers take a
commit flag now, and delete_profile passes commit=False so the single
db.commit() at its end publishes the entire cascade. Other callers keep the
default and are unchanged.