I think it's a matter of language. We cannot define "factorial" as both the result of a series of mulitplications and as the number of permutations of items in a set. If it is the latter, the ! operator becomes a mere algorithm, a function of n. That function can be defined as a series of multiplications for n>0 and as 1 for n=0 and be undefined for negative numbers. (The multiplication definition simply does not work for zero, so if the ! operator refers to multiplication, it cannot apply to 0.)
As a non-mathematician, I only know what I can pick up by a bit of reading, which is, of course, a dangerous thing. Still, some sources seem to describe the factorial algorithm as a function of non-negative integers, and others as a function of positive integers. But, as you have shown, if 0! =1, a whole lot of other useful things can be done that would be much clunkier (if not impossible) if 0! were undefined. Thus, I am not suggesting that 0! is undefined. I am suggesting that it is defined as 1.
Consider some other zero operations. n+0=n not because adding nothing to something leaves that thing unchaned, but because you cannot add nothing to anything. If there is nothing being added, then adding isn't happening. But we need a special result from applying the "+0" operator. So we say that n+0=n.
Ditto for multiplication. You cannot have more than one of nothing, so "multiplication" of zero is not a real thing in the real world. You can have none of something, but one would expect that 0 could be either multipller or the multiplicand if the result of multiplying by zero were something that could be calculated. Rather, I think it better to say that the result of applying the "*0" operator is 0.
0! factorial fits this model for me. The ! operator when applied to a positive number produces the product of itself and the positive integers below it. (Note that 0 is not included in the multiplication.) As a special case, the ! operator produces 1 when applied to zero. Your proof works in the sense that 0! must equal 1, but only in the way that 7+0 must equal 7, not because it captures the number of ways the empty set can be arraned (which I maintain is zero, because there is nothing in the set to arrange), but because we need it to be 1 for other reasons, including the nCr example where n=r.