How do you imagine types would prevent this? No matter how I think about types in this context, I think a runtime check of "is this ID an app ID?" is mandatory in order to truly prevent this (alternatively- different URLs/parameter names to delete an app and a site)
Yes, you're certainly right that this check would have to happen at runtime (unless Atlassian have written one big project which is all checked by a compiler, which I highly doubt).
How I imagine this to work would be that the team who wrote the system (function, script, whatever) for deleting things would encode it in the types that their deletion system would only accept specifically app IDs, rather than both app IDs and site IDs (which I think reflects the specifics of their post-mortem).
In order to get a value into the deletion system for processing, the ID value would need to be parsed into the specific type that the deletion system accepts.
This is of course similar to just saying there should have been validation, but I think conceptually, validation and parsing into a narrower type are two different things. Gary Bernhardt calls this "functional core, imperative shell". Michael Feathers calls this "edge-free programming". Probably the best literature on this difference is by Alexis King, here: https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va...
Yet another case where using types would have prevented a massive problem.